Standalone integration for Sygic2D

Introduction

NOTE: We strongly recommend chosing integration with a lastest 3D version of Sygic Professional Navigation.

In the following we will guide you through creating a simple Android application integrating Sygic navigation engine with a standalone integration (Sygic runs on a separate screen in the fullscreen mode).
In this example we will develop a simple application, where you can type in an address string and through a custom button you can start navigation to that address.

Prepare your working environment

For being able to compile your application you need to have Eclipse ADT on your computer. If you don't have it please follow Download Eclipse ADT.
As the key point you need to Download and Install SDK library on your computer.
You may want to install the Sygic navigation on your device in advance. Check Installation of navigation. You will definitely need it at later stages when you want to test your application on device.
Not necessarily but we recommend first to test the compilation flow using the IpcDemo2D project within the Sygic SDK package. Check Run Demo Example.

Create new project

Let's start Eclipse and create the new project through File -> New -> Android Application Project.
The project is automatically populated with several files, while these are relevant.

  • MainActivity.java, which is the placeholder for application coding (java code)
  • activity_main.xml, which will define graphical look of application (layout form)

The java code should be generated as follows:

package com.example.myapp;
import android.app.Activity;
import android.os.Bundle;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

The layout form should be generated as follows:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="${packageName}.${activityClass}" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />

</RelativeLayout>

Include Sygic library

Including Sygic SDK library consists of two steps:

  • copy remoteAPI.jar from SDK package to project's Lib folder
    The Sygic Library should automatically appear in project (possibly click on refresh) as shown here:

  • add import references of Sygic packages into java code
    Note that these references might be automatically added when writing java code.
    Finally the import section should look as shown here:

import com.sygic.sdk.remoteapi.Api;
import com.sygic.sdk.remoteapi.ApiCallback;
import com.sygic.sdk.remoteapi.ApiNavigation;
import com.sygic.sdk.remoteapi.events.ApiEvents;
import com.sygic.sdk.remoteapi.exception.NavigationException;

Note that all Sygic classes and functions are located in the package com.sygic.sdk.remoteapi.

Define graphical look

As envisioned we add two graphical elements into application, which is the EditText for inputting address and Button for triggering navigation functions.
Thus we need to modify the default generated layout to the following form.

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="${packageName}.${activityClass}" >

    <EditText
        android:id="@+id/editAddress"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:ems="10" >
        <requestFocus />
    </EditText>

    <Button
        android:id="@+id/btnNavigate"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_below="@+id/editAddress"
        android:text="Navigate" />

</RelativeLayout>

Code the application

The application will be written solely in the java class MainActivity.

Define application framework using Sygic callback mechanism

The following code is the typical framework to pick when starting to write an application using Sygic API.

public class MainActivity extends Activity {

    private Api mApi;
    private ApiCallback mApiCallback = new ApiCallback() {

        @Override
        public void onServiceDisconnected() {
        }

        @Override
        public void onServiceConnected() {
        }

        @Override
        public void onEvent(int event, String data) {
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mApi = Api.init(getApplicationContext(), ... , mApiCallback);
    }
}

The activity class needs to contain the instance of Sygic Api (mApi) and the instance of ApiCallback (mApiCallback).
The ApiCallback as the interface defines 3 functions mandatory to fill (onServiceConnected, onServiceDisconnected, onEvent).
In this example we will only use onServiceConnected. The other two functions we can leave empty in this example.
With the applicaton start (the application basically starts at OnCreate) we need to call the mApi.init function, which binds API with the defined callback and with Sygic navigation.

Bind API to Sygic Navigation engine

The binding means filling the appropriate application and service identificators into mApi.init function. in this example we use com.sygic.drive, which corresponds to Sygic 2D Fleet Navigation.

  mApi = Api.init(getApplicationContext(), "com.sygic.drive", "com.sygic.drive.SygicService", mApiCallback);

Define API opening and closing operations

The opening of API interface is implemented with calling connect at the application start right after init as follows:

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mApi = Api.init(getApplicationContext(), ... , mApiCallback);
        mApi.connect();
    }

and registerCallback, which typically resides in onServiceConnected

@Override
        public void onServiceConnected() {
            try {
                mApi.registerCallback();
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }

Next, we want to close API with an application exit, and the typical choice is to place unregisterCallback and disconnect inside the application's onDestroy method as follows:

@Override
    protected void onDestroy() {
        try {
            mApi.unregisterCallback();
        } catch (RemoteException e) {
            e.printStackTrace();
        }
        mApi.disconnect();
        super.onDestroy();
    }

Invoke navigation function

We will call the navigation function from the button click on our designed button by filling its event function OnClick.
Inside OnClick we will read the user typed address and use it in the API function call NavigateToAddress.
Thus the whole function can be defined within default activity OnCreate function as follows:

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button btnNavigate = (Button)findViewById(R.id.btnNavigate);
        btnNavigate.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                String address = ((EditText)findViewById(R.id.editAddress)).getText().toString();
                try {
                    mApi.show(false);
                    ApiNavigation.navigateToAddress(address, false, 0, 0);
                } catch (NavigationException e) {
                    e.printStackTrace();
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }

        });

        mApi = Api.init(getApplicationContext(), "com.sygic.drive", "com.sygic.drive.SygicService", mApiCallback);
        mApi.connect();
    }

Build and deploy application

Building the application is simple as clicking on Run button in Eclipse.
The result of the build process is generation of MyApp.apk, which just needs to be copied to your Android device.
You also need to copy and install Sygic Navigation to device. Please note in this example it should be Sygic 2D Navigation.
For binding to other versions of navigation please change the application identificator inside the Api.init function.
If you have not done that yet please follow Installation of navigation.

Full sample reference

package com.example.myapp;
import android.app.Activity;
import android.os.Bundle;
import android.os.RemoteException;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.sygic.sdk.remoteapi.Api;
import com.sygic.sdk.remoteapi.ApiCallback;
import com.sygic.sdk.remoteapi.ApiNavigation;
import com.sygic.sdk.remoteapi.events.ApiEvents;
import com.sygic.sdk.remoteapi.exception.NavigationException;

public class MainActivity extends Activity {

    private Api mApi;

    private ApiCallback mApiCallback = new ApiCallback() {

        @Override
        public void onServiceDisconnected() {
        }

        @Override
        public void onServiceConnected() {
            try {
                mApi.registerCallback();
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onEvent(int event, String data) {
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button btnNavigate = (Button)findViewById(R.id.btnNavigate);
        btnNavigate.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                String address = ((EditText)findViewById(R.id.editAddress)).getText().toString();
                try {
                    mApi.show(false);
                    ApiNavigation.navigateToAddress(address, false, 0, 0);
                } catch (NavigationException e) {
                    e.printStackTrace();
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }

        });

        mApi = Api.init(getApplicationContext(), "com.sygic.drive", "com.sygic.drive.SygicService", mApiCallback);
        mApi.connect();
    }

    @Override
    protected void onDestroy() {
        try {
            mApi.unregisterCallback();
        } catch (RemoteException e) {
            e.printStackTrace();
        }
        mApi.disconnect();
        super.onDestroy();
    }
}