DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
  1. DZone
  2. Testing, Deployment, and Maintenance
  3. Deployment
  4. Real-Time Interaction With HERE Maps Between Android and JavaScript With Socket.io

Real-Time Interaction With HERE Maps Between Android and JavaScript With Socket.io

We introduce Android communication so that way as a user interacts with a map, those interactions get broadcasted to all similar platforms.

Nic Raboy user avatar by
Nic Raboy
·
Apr. 19, 19 · Tutorial
Like (2)
Save
Tweet
Share
8.04K Views

Join the DZone community and get the full member experience.

Join For Free

If you've been keeping up with my content, you might remember that about a week ago I had written a tutorial around real-time interaction using Socket.io and a HERE map. This tutorial titled, Real-Time Interaction Between Maps with Socket.io and JavaScript, demonstrated how Socket.io could be used to send client interactions with a map to a server and then broadcasted in real-time to all other connected clients, showing the results on the screen.

We're going to take things a step further in this tutorial. Instead of web browser to web browser communication, we're going to introduce Android communication so that way as a user interacts with a map, whether it be in a web browser or on an Android device, those interactions get broadcasted to all similar platforms.

To get an idea of what we hope to accomplish, take a look at the following animated image:

Clicking an area on the Android map will add a marker to the Android map as well as all connected web browser and Android clients. Likewise, clicking an area on the web browser map will do the same.

The code for the Socket.io server and JavaScript client that we saw in the other tutorial have not changed for this tutorial. For this reason, we won't be exploring these again even though they'll be heavily referenced. Definitely consult my previous tutorial if you haven't already.

Configuring an Android Application to Use Socket.io

Using Socket.io in Android with Java isn't too different than using it with JavaScript. For the most part the APIs are the same. However, being that this is Android, there are some project level configurations that must happen first.

If you've never used HERE with Android, I suggest you check out my previous tutorial titled, Getting Started with HERE Maps in an Android Application. We won't be walking through the steps to configure HERE in this tutorial, only how to use it with Socket.io.

Open your project's build.gradle file because we need to have Gradle import our Socket.io dependency. Within this file, include the following:

dependencies {
    // ...
    implementation ('io.socket:socket.io-client:1.0.0') {
        exclude group: 'org.json', module: 'json'
    }
}

You'll want to include the library in your dependencies block without removing the other dependencies that are already in there. Once we have Socket.io as part of our project through Gradle, we need to make some changes to the project manifest file. Open the project's AndroidManifest.xml file and make the following changes:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.raboy">
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme"
        android:hardwareAccelerated="true"
        android:usesCleartextTraffic="true">
        <meta-data android:name="com.here.android.maps.appid" android:value="APP_ID_HERE"/>
        <meta-data android:name="com.here.android.maps.apptoken" android:value="APP_CODE_HERE"/>
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

Much of the AndroidManifest.xml file is based on configurations that you've probably made for the HERE Android SDK. What we're looking for in particular when it comes to Socket.io is the following line:

android:usesCleartextTraffic="true"

It took me quite a while to figure out that the above line was needed. In older versions of Android it's not necessary to explicitly allow cleartext traffic, but in more modern versions, like the Android Pie simulator that I'm using, it is a requirement, otherwise our socket connections will never establish.

At this point in time we're actually ready to start using Socket.io with HERE in our Android application.

Sending Data and Responding to Events Visually With a HERE Map

Before we start throwing in code, let's understand how our application is going to work. Essentially we have two parts when it come to Socket.io.

When we click on the map, a gesture event will trigger which will allow us to convert the pixel information into coordinate information. Using those coordinates we will send them to our Socket.io server. That is the first part.

The second part will be around receiving coordinate information. The server will be sending all connected clients, both JavaScript and Android, broadcasts as they are received. In Android we need to listen for them and take the position data in them and turn them into markers.

So let's get up to speed when it comes to our Android code. In the MainActivity.java file you probably have something like this:

public class MainActivity extends AppCompatActivity {

    private Map map = null;
    private SupportMapFragment mapFragment = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.mapfragment);
        mapFragment.init(new OnEngineInitListener() {
            @Override
            public void onEngineInitializationCompleted(OnEngineInitListener.Error error) {
                if (error == OnEngineInitListener.Error.NONE) {
                    map = mapFragment.getMap();
                    map.setCenter(new GeoCoordinate(37.7394, -121.4366, 0.0), Map.Animation.NONE);
                    map.setZoomLevel(12);
                }
            }
        });
    }

}

As part of our first step, we are going to establish a connection to the Socket.io server that we built with Node.js in the previous tutorial. First create a private variable like the following:

private Socket socket;

It is up to you where we actually try to establish a connection, but wherever we decide, we'll need to catch any possible exceptions. Let's modify our code to look like the following:

public class MainActivity extends AppCompatActivity {

    private Map map = null;
    private SupportMapFragment mapFragment = null;
    private Socket socket;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        try {
            socket = IO.socket("http://10.0.2.2:3000");
            socket.connect();
            mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.mapfragment);
            mapFragment.init(new OnEngineInitListener() {
                @Override
                public void onEngineInitializationCompleted(OnEngineInitListener.Error error) {
                    if (error == OnEngineInitListener.Error.NONE) {
                        map = mapFragment.getMap();
                        map.setCenter(new GeoCoordinate(37.7394, -121.4366, 0.0), Map.Animation.NONE);
                        map.setZoomLevel(12);
                    }
                }
            });
        } catch (URISyntaxException e) {
            Log.e("HERE", e.getMessage());
        }
    }

}

Notice that we've added two particular lines in the above code. In my circumstance, my Socket.io server is running on my local computer and I'm using my Android simulator. For this reason, I cannot connect my simulator to localhost, so I have to use 10.0.2.2 instead. After defining the server information, then we can try to connect.

Since we've already got a functional JavaScript application that is sending marker information, let's listen for that information as part of our next step.

Within the onEngineInitializationCompleted method, add the following:

socket.on("marker", new Emitter.Listener() {
    @Override
    public void call(Object... args) {
        try {
            JSONObject position = (JSONObject) args[0];
            MapMarker defaultMarker = new MapMarker();
            defaultMarker.setCoordinate(new GeoCoordinate(position.getDouble("lat"), position.getDouble("lng"), 0.0));
            map.addMapObject(defaultMarker);
        } catch (JSONException e) {
            Log.e("HERE", e.getMessage());
        }
    }
});

In the above code, we are listening for marker events or labels, which is what the server is configured to send. When we receive one of those events, we can convert it into JSON and extract the lat and lng values to be used in a MapMarker. Once we have our MapMarker we can add it to the map.

If the server is storing a bunch of markers, when you launch your Android application, they should all start to populate.

We want Android to be able to send marker data as well, not just JavaScript. After our marker event, add the following:

mapFragment.getMapGesture().addOnGestureListener(new MapGesture.OnGestureListener.OnGestureListenerAdapter() {
    @Override
    public boolean onTapEvent(PointF p) {
        GeoCoordinate position = map.pixelToGeo(p);
        try {
            JSONObject pos = new JSONObject();
            pos.put("lat", position.getLatitude());
            pos.put("lng", position.getLongitude());
            socket.emit("marker", pos);
        } catch (JSONException e) {
            Log.e("HERE", e.getMessage());
        }
        return false;
    }
});

What we're saying in the above code is that when a tap event occurs, calculate the coordinates based on the pixels and add them to a JSON object. We then send that JSON object to the Socket.io server to be broadcasted.

Conclusion

You just saw how to use Socket.io with Android to send tap information to other connected Android and JavaScript devices to be converted into markers on a map. By doing this, a real-time interactive experience is created HERE that is carried between platforms.

If you need help with the JavaScript side of things, I encourage you to check out my previous tutorial which focuses on the Socket.io server and JavaScript web application.

Android (robot) Socket.IO JavaScript HERE Maps (app) Interaction application

Published at DZone with permission of Nic Raboy, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • Stream Processing vs. Batch Processing: What to Know
  • Quick Pattern-Matching Queries in PostgreSQL and YugabyteDB
  • Utilize OpenAI API to Extract Information From PDF Files
  • Agile Transformation With ChatGPT or McBoston?

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: