I have written an Android app that communicates to my Raspberry Pi over SSH (using JSch) but the issue is that in the App the IP address of my Raspberry Pi has been hardcoded at 192.168.1.109 - ideally it would be good to be able to give it a local name, something like garagedoor.local - something that won't change when the DHCP assigns a different IP address.
It turns out that the way to do this isn't difficult on the Raspberry Pi and most of work is in changes to the Android App needed to make it happen. I've numbered the steps 1-4.
1. Configuration of your Raspberry Pi.
# Get superuser privileges
sudo su
# Change the host name of your Raspberry Pi from "raspberrypi" to "garagedoor"
# Reference: http://www.howtogeek.com/167195/how-to-change-your-raspberry-pi-or-other-linux-devices-hostname/
sudo nano /etc/hosts # <== Replace raspberrypi with garagedoor
sudo nano /etc/hostname # <== Replace raspberrypi with garagedoor
sudo /etc/init.d/hostname.sh # Commit the changes.
sudo reboot # Reboot
# Install the mDNS implementation - avahi
# Reference: http://www.howtogeek.com/167190/how-and-why-to-assign-the-.local-domain-to-your-raspberry-pi/
# Get superuser privileges
sudo su
# Update the package sources
apt-get update
# Ugrade the packages
apt-get upgrade
# Install the mDNS implementation - avahi
sudo apt-get install avahi-daemon
That's the end of the changes needed on your Raspberry Pi.
2. Test on either Windows, Linux or Mac OSX that the Raspberry Pi is visible on the network with its new name of "garagedoor.local".
On Windows, you will need to have Bonjour Networking Services installed, which comes bundled with iTunes.
Run a cmd.exe prompt and type the command ping garagedoor.local -- you should get a response from your Raspberry Pi.
On Mac OSX, Bonjour Networking Services are installed by default.
In a bash terminal window, type the command ping garagedoor.local -- you should get a response from your Raspberry Pi.
On Linux, first ensure you have installed the avahi-daemon package.
In a bash terminal window, type the command ping garagedoor.local -- you should get a response from your Raspberry Pi.
3. Using NSD (Network Service Discovery) on Android to resolve the Raspberry Pi's service name.
Browsers and terminal programs on Android won't be able to resolve the garagedoor.local since to do this requires use of either the official Network Service Discovery library (supported by API Level 16 up) or the open source Java Zeroconf library named jMDNS.
In my case, I am using a custom app I wrote to communicate to the Raspberry Pi, so I have decided just to use the Network Service Discovery library.
4. Source code changes needed in the Android App to support NSD (Network Service Discovery)
Notes:
(1) Below is just how I decided to implement it, you may want to separate the NSD related code out of the Activity into its own class, but for me that wasn't a problem.
(2) I probably need to do something related to NSD in the Application lifecycle events of onPause(), onResume(), onDestroy() and onTeardown(). I haven't done that here yet.
4.A. Add some members to the Activity
I added this to my MainActivity but my app is small and so that's all I needed to do.
// Network Service Discovery related members
// This allows the app to discover the garagedoor.local
// "service" on the local network.
// Reference: http://developer.android.com/training/connect-devices-wirelessly/nsd.html
private NsdManager mNsdManager;
private NsdManager.DiscoveryListener mDiscoveryListener;
private NsdManager.ResolveListener mResolveListener;
private NsdServiceInfo mServiceInfo;
public String mRPiAddress;
// The NSD service type that the RPi exposes.
private static final String SERVICE_TYPE = "_workstation._tcp.";
4.B. Add some init code to the bottom of the Activity's onCreate() method.
mRPiAddress = "";
mNsdManager = (NsdManager)(getApplicationContext().getSystemService(Context.NSD_SERVICE));
initializeResolveListener();
initializeDiscoveryListener();
mNsdManager.discoverServices(SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD, mDiscoveryListener);
4.C. Add the following two new methods to your Activity.
private void initializeDiscoveryListener() {
// Instantiate a new DiscoveryListener
mDiscoveryListener = new NsdManager.DiscoveryListener() {
// Called as soon as service discovery begins.
@Override
public void onDiscoveryStarted(String regType) {
}
@Override
public void onServiceFound(NsdServiceInfo service) {
// A service was found! Do something with it.
String name = service.getServiceName();
String type = service.getServiceType();
Log.d("NSD", "Service Name=" + name);
Log.d("NSD", "Service Type=" + type);
if (type.equals(SERVICE_TYPE) && name.contains("garagedoor")) {
Log.d("NSD", "Service Found @ '" + name + "'");
mNsdManager.resolveService(service, mResolveListener);
}
}
@Override
public void onServiceLost(NsdServiceInfo service) {
// When the network service is no longer available.
// Internal bookkeeping code goes here.
}
@Override
public void onDiscoveryStopped(String serviceType) {
}
@Override
public void onStartDiscoveryFailed(String serviceType, int errorCode) {
mNsdManager.stopServiceDiscovery(this);
}
@Override
public void onStopDiscoveryFailed(String serviceType, int errorCode) {
mNsdManager.stopServiceDiscovery(this);
}
};
}
private void initializeResolveListener() {
mResolveListener = new NsdManager.ResolveListener() {
@Override
public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) {
// Called when the resolve fails. Use the error code to debug.
Log.e("NSD", "Resolve failed" + errorCode);
}
@Override
public void onServiceResolved(NsdServiceInfo serviceInfo) {
mServiceInfo = serviceInfo;
// Port is being returned as 9. Not needed.
//int port = mServiceInfo.getPort();
InetAddress host = mServiceInfo.getHost();
String address = host.getHostAddress();
Log.d("NSD", "Resolved address = " + address);
mRPiAddress = address;
}
};
}
4.D. Make use of the mRPiAddress member where previously you used a hardcoded IP address.
Check that its not empty before using it. If its empty, it means the RPi's name couldn't be resolved.
Follow @dodgy_coder
Subscribe to posts via RSS
"The cost of intelligence is hyper-deflating faster than Moore's Law; we are moving to a world of intelligence surplus" -Marc Andreessen, Jan 2026
Showing posts with label java. Show all posts
Showing posts with label java. Show all posts
Saturday, February 28, 2015
Saturday, November 22, 2014
Android development is the new .NET
Back in 2001 Microsoft Windows had 90% of the worldwide OS market for PCs. But desktop windows software development was dire.
Developers were using tools like ...
Fast forward to 2014, Android now has an 80% worldwide market share of approx. 1.75 billion smart phones.
Google has their own IDE, Android Studio and the open source Android SDK, which you can program using Java or any other JVM language. In the same way that .NET lets you use different .NET compatible languages such as C++/CLI and F#, Android supports other JVM languages like Scala, Clojure and Groovy, all of which let you cut down on the verbosity and boilerplate of Java.
Google is attempting to bring as many developers over to Android as possible. Their Head of Scalable Developer Relations, Reto Meier, aims to bring 50 million developers to Android.
Based on Android's market share and future employment prospects, Android is a decent choice for developers to try out. Compared to iOS, Android isn't as performant or profitable, but now it has a decent IDE, the weight of numbers, and the capability to use many Java FOSS libraries.
Follow @dodgy_coder
Subscribe to posts via RSS
Developers were using tools like ...
- Visual Basic 6 - very productive, with the downside of ugly, primitive syntax, lacking modern features such as interfaces and classes.
- Visual C++/MFC - serious windows developers were using this, but it was less productive and extremely verbose, with lots of boilerplate.
- Delphi - the successor of Turbo Pascal and possibly the best of all frameworks on Windows at the time, but it never really took off.
- Borland C++/OWL - the Open Windows Library from Borland tracked pretty closely with Visual C++/MFC, verbose + boilerplate.
- Java - this had a reputation on Windows at the time for slow performance, bad visuals and bad tools.
Fast forward to 2014, Android now has an 80% worldwide market share of approx. 1.75 billion smart phones.
Google has their own IDE, Android Studio and the open source Android SDK, which you can program using Java or any other JVM language. In the same way that .NET lets you use different .NET compatible languages such as C++/CLI and F#, Android supports other JVM languages like Scala, Clojure and Groovy, all of which let you cut down on the verbosity and boilerplate of Java.
Google is attempting to bring as many developers over to Android as possible. Their Head of Scalable Developer Relations, Reto Meier, aims to bring 50 million developers to Android.
Based on Android's market share and future employment prospects, Android is a decent choice for developers to try out. Compared to iOS, Android isn't as performant or profitable, but now it has a decent IDE, the weight of numbers, and the capability to use many Java FOSS libraries.
Follow @dodgy_coder
Subscribe to posts via RSS
Subscribe to:
Posts (Atom)