Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 4 Next »

Way Finding (Static and Dynamic) Integrations

The following guide provides complete instructions and code snippets for the SDK integration for your Android LBS (Mapping) experience in your apps.

The first three sections are for both Routing and Blue Dot (static and dynamic way finding).

The last two sections exclusively are for Blue Dot (dynamic way finding or turn-by-turn).

Android Installation - Getting Started

This guide is a quick start to adding a Phunware Map to an Android app.  Android Studio is the recommended development environment for building an app with the Phunware Mapping SDK.

 


Step 1- Add the Phunware Maven remote repository.

Insert this block into allprojects -> repositories:

allprojects {
    repositories {
 
		maven {
    		url "https://nexus.phunware.com/content/groups/public/"
		}
    }
}

 

 

Step 2 - Add the Mapping SDK as a dependency in your app's build.gradle file

This one line includes all dependencies necessary to use the Phunware Mapping SDK.

apply plugin: 'com.android.application'

android {
	...
}

dependencies {
	...
    compile 'com.phunware.mapping:mapping:3.1.0'
    ...
}

 

 

Step 3 - Add your Google Maps Api Key to AndroidManifest.xml

Create a string resource that contains your Google Maps API Key.  

If you need help getting a Google Maps API Key,  please find instructions here: Get a Google Maps API key

 

 

<meta-data android:name="com.google.android.geo.API_KEY" 
           android:value="@string/google_maps_api_key"/>

 

 

Step 4 - Add Phunware keys for App Id, Access Key, Signature Key and Encryption Key

Your App Id, Access Key, Signature Key and Encryption Key are found on the MaaS portal on the Applications tab. 

<meta-data android:name="com.phunware.APPLICATION_ID" android:value="@string/app_id" />
<meta-data android:name="com.phunware.ACCESS_KEY" android:value="@string/access_key" />
<meta-data android:name="com.phunware.SIGNATURE_KEY" android:value="@string/signature_key" />
<meta-data android:name="com.phunware.ENCRYPTION_KEY" android:value="@string/encrypt_key" />

 

 

Step 5 - Add MapFragment to your layout

This is where the Phunware Mapping SDK will render the map.  

NOTE: the fragment will be found via the R.id.map id.

<fragment xmlns:android="http://schemas.android.com/apk/res/android"
        android:name="com.phunware.mapping.MapFragment"
        android:id="@+id/map"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

 

 

Step 6 - Get the Map asynchronously in your activity:

The PhunwareMapManager is created and the Phunware API keys are registered in this step.

Then the MapFragment is located and the map is loaded asynchronously.  

Your implementation of OnPhunwareMapReadyCallback will be called when the map is ready.

 

	private PhunwareMapManager mapManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

		...

        mapManager = PhunwareMapManager.create(this);

        // register the Phunware API keys
        PwCoreSession.getInstance().registerKeys(this);

        MapFragment mapFragment = (MapFragment) getFragmentManager()
                .findFragmentById(R.id.map);
        if (mapFragment != null) {
            mapFragment.getPhunwareMapAsync(this);
        }
    }

 

 

Step 7 - Make sure your activity implements OnPhunwareMapReadyCallback

Once the PhunwareMap is ready, set it in the PhunwareMapManager and add a building by id.

Building additions are also asynchronous,  so a callback will notify you of success or failure.

public class MainActivity extends AppCompatActivity implements OnPhunwareMapReadyCallback {

	...
	
    @Override
    public void onPhunwareMapReady(PhunwareMap phunwareMap) {
        mapManager.setPhunwareMap(phunwareMap);

        mapManager.addBuilding(getResources().getInteger(R.integer.building_id),
                new Callback<Building>() {
            @Override
            public void onSuccess(Building building) {
            }

            @Override
            public void onFailure(Throwable throwable) {
            }
        });        
    }

 

 

Step 8 - Do something interesting with the Building

Once the map and building are loaded, move and zoom the view so you can see the initial floor.

public class MainActivity extends AppCompatActivity implements OnPhunwareMapReadyCallback {
    @Override
    public void onPhunwareMapReady(final PhunwareMap phunwareMap) {
        mapManager.setPhunwareMap(phunwareMap);

        mapManager.addBuilding(getResources().getInteger(R.integer.building_id),
                new Callback<Building>() {
            @Override
            public void onSuccess(Building building) {
                FloorOptions initialFloor = building.initialFloor();
                building.selectFloor(initialFloor.getLevel());
                // animate the camera to the building at an appropriate zoom level
                // so we can see the building
                CameraUpdate cameraUpdate = CameraUpdateFactory
                        .newLatLngBounds(initialFloor.getBounds(), 4);
                phunwareMap.getGoogleMap().animateCamera(cameraUpdate);
            }
            @Override
            public void onFailure(Throwable throwable) {
            }
        });        
    }

 

 

Getting POI info from a Map Marker

The Mapping SDK associates a PointOptions object with its associated Google map marker object.

 

 

When setting up InfoWindow click listeners,  you can access the POI info from the marker by calling the getTag() method on the marker and cast it to PointOptions.

map.getGoogleMap().setOnInfoWindowClickListener(new GoogleMap.OnInfoWindowClickListener() {
    @Override
    public void onInfoWindowClick(Marker marker) {
        PointOptions point = (PointOptions) marker.getTag();
		if (point != null) {
	        long floorId = point.getFloorId();
    	    String name = point.getName();
		}
    }
});

 

 

Using a MapView in a Custom Layout

MapView is a subclass of the Google Maps MapView class.  It can be used to place a map in any Android View.

Users of the MapView class must forward all the activity lifecycle methods to the corresponding methods in the MapView class. Examples of these methods include onCreate(), onDestroy(), onResume() and onPause().

 


SimpleMapViewFragment.java

public class SimpleMapViewFragment extends Fragment implements OnPhunwareMapReadyCallback {

    private static final String TAG = SimpleMapViewFragment.class.getSimpleName();

    private PhunwareMapManager mapManager;
    private MapView mapView;

    public static SimpleMapViewFragment newInstance() {
        SimpleMapViewFragment fragment = new SimpleMapViewFragment();

        Bundle args = new Bundle();
        fragment.setArguments(args);

        return fragment;
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mapManager = ((App)getActivity().getApplication()).getMapManager();
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
            @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_map, container, false);

        mapView = (MapView)view.findViewById(R.id.map_view);
        mapView.onCreate(savedInstanceState);

        mapView.getPhunwareMapAsync(this);

        return view;
    }

    @Override
    public void onResume() {
        super.onResume();
        mapView.onResume();
    }

    @Override
    public void onPause() {
        mapView.onPause();
        super.onPause();
    }

    @Override
    public void onDestroy() {
        mapView.onDestroy();
        super.onDestroy();
    }

    @Override
    public void onLowMemory() {
        super.onLowMemory();
        mapView.onLowMemory();
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        mapView.onSaveInstanceState(outState);
    }

    @Override
    public void onPhunwareMapReady(final PhunwareMap map) {

        mapManager.setPhunwareMap(map);
        mapManager.addBuilding(getResources().getInteger(R.integer.building_id),
                new Callback<Building>() {
                    @Override
                    public void onSuccess(final Building building) {
                        if (building == null) {
                            Toast.makeText(getActivity(), "No building", Toast.LENGTH_LONG)
                                    .show();
                            return;
                        }

                        // animate the camera to the new building
                        final CameraUpdate cameraUpdate;
                        FloorOptions initialFloor = building.initialFloor();
                        if (initialFloor == null) {
                            // if we don't have a floor with reference points, just zoom in on the
                            // building, at a relatively safe distance
                            cameraUpdate = CameraUpdateFactory
                                    .newLatLngZoom(building.getLocation(), 17);
                        } else {
                            building.selectFloor(building.getInitialFloor());
                            cameraUpdate = CameraUpdateFactory
                                    .newLatLngBounds(initialFloor.getBounds(), 4);
                        }
                        map.getGoogleMap().setOnMapLoadedCallback(new GoogleMap.OnMapLoadedCallback() {
                            // Wait to animate the camera until the map is rendered.
                            @Override
                            public void onMapLoaded() {
                                map.getGoogleMap().animateCamera(cameraUpdate);
                            }
                        });

                        // enable my location (blue dot)
                        mapManager.setMyLocationEnabled(true);
                    }

                    @Override
                    public void onFailure(final Throwable e) {
                        getActivity().runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                Toast.makeText(getActivity(), e.getLocalizedMessage(),
                                        Toast.LENGTH_LONG).show();
                            }
                        });
                    }
                });
    }
}

 

 

fragment_map.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.phunware.mapping.MapView
        android:id="@+id/map_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:clipToPadding="false"
        android:paddingBottom="48dp" />

</android.support.design.widget.CoordinatorLayout>

 

 

Dynamic Way Finding Signal Provider Integrations

 

Integrating a Location Provider

 

In order to show the user's current location,  you must add a Location Provider, which updates location information.

Phunware's location providers:

Provider
Setting Keys
Compile Statement
Description
BLE
  • Map Key
  • Customer ID
com.phunware.location:provider-senion:3.0.0
Senion Lab BLE (bluetooth low energy) location provider
CMX (MSE)

Venue GUID

com.phunware.location:provider-cmx:3.0.0
Cisco Hyperlocation (wifi) location provider
GPS 
com.phunware.location:provider-gps:3.0.0
GPS location provider

 

 

NOTE: Additional providers, Beacon Point and Mist are integrated as as Managed Providers. 

NOTE:Managed Provider must be built and set on my MapManager after the the map is ready and the building has been loaded.

Step 1 -  Add a location provider as a compile dependency

apply plugin: 'com.android.application' 
android {
    ...
}
 
dependencies {
    ...
    compile 'com.phunware.mapping:mapping:3.1.0'
    compile 'com.phunware.location:provider-senion:3.1.0'
    ...
}

 

 

Step 2 -  Set the Location Provider and Enable Location Updates

The PhunwareMapManager is told what provider is being used to get location updates.

As seen the code snippet, the Senion Location Provider requires a customer id and map id.  The method getSenionFloorMap() returns a HashMap of Senion floor ids to MaaS floor ids.

 

NOTE: You must pass a building object to the setLocationManager() method on PhunwareMapManager.

The call to setMyLocationEnabled() allows you to control when the blue dot is rendered.

@Override    
public void onPhunwareMapReady(PhunwareMap phunwareMap) {
	mapManager.setPhunwareMap(map);
	mapManager.addBuilding(getResources().getInteger(R.integer.building_id),
        new Callback<Building>() {
            @Override
            public void onSuccess(final Building building) {
				...

                mapManager.setLocationProvider(SenionProviderFactory.create(this,
                        getString(R.string.sl_customer_id),
                        getString(R.string.sl_map_id),
                        getSenionFloorMap()).createLocationProvider(), building);

                // enable my location (blue dot)
                mapManager.setMyLocationEnabled(true);

				...
            }

            @Override
            public void onFailure(Throwable e) {
            }
        });
}

 

 

Step 3 - Manage Location Updates when in the Background

Constant location updating in the background will drain a signal device's battery.  To prevent this, Phunware uses intercept activity lifecycle methods to disable and enable location updates.

@Override
protected void onPause() {
    super.onPause();
    if (mapManager != null) {
        mapManager.setMyLocationEnabled(false);
    }
}

@Override
protected void onResume() {
    super.onResume();

    if (mapManager != null) {
        mapManager.setMyLocationEnabled(true);
    }
}

 

 

Integrating a Managed Provider

 

Managed Providers offer a combination of signal location providers. This combination results in higher accuracy rates for location in dynamic way finding.

 


Step 1 - Add the Phunware Maven remote repository. Insert this block into allprojects -> repositories:

allprojects {
    repositories {
        maven {
            url "https://nexus.phunware.com/content/groups/public/"
        }
    }
}

 

 

Step 2 - Add Phunware key resources to strings.xml for App Id, Access Key, Signature Key

Navigate to the MaaS portal, find your app, and add your access key and signature key to setup your application.

<string name="app_Id">APPID</string>
<string name="access_Key">ACCESSKEY</string>
<string name="sig_Key">SIGKEY</string>

 

 


Step 3 - Add Phunware keys for App Id, Access Key, and Signature Key to Manifest

NOTE: The encryption key may not be provided in portal under your app's settings. If it isn't, you may leave it empty.



<meta-data
    android:name="com.phunware.APPLICATION_ID"
    android:value="@string/app_id"/>
<meta-data
    android:name="com.phunware.ACCESS_KEY"
    android:value="@string/access_key"/>
<meta-data
    android:name="com.phunware.SIGNATURE_KEY"
    android:value="@string/signature_key"/>
<meta-data
    android:name="com.phunware.ENCRYPTION_KEY"
    android:value="@string/encrypt_key"/>

 

 


Step 4 - Add managed provider as a compile dependency.


apply plugin: 'com.android.application'
android {
	...
}
 
dependencies {
	...
	compile 'com.phunware.mapping:mapping:3.1.0'
	compile 'com.phunware.location:provider-managed:3.1.0'
	...
} 

 

 


Step 5 - Set the Location Provider on the PhunwareMapManager

 


The following values are needed to build a ManagedProvider:

  • application: reference to the users application
  • context: context of the application
  • venueId: Id of the venue/building you currently have loaded
  • (optional) Senion values
    • slCustomerId: The customer ID provided by Senion
    • slMapKey: the map key provided by senion
  •  (optional) Beacon Point values
    • bpOrgId: the orgId provided by Beacon Point



@Override
public void onPhunwareMapReady(final PhunwareMap phunwareMap) {
    mapManager.setPhunwareMap(phunwareMap);
    this.phunwareMap = phunwareMap;

    mapManager.addBuilding(buildingId, venueGuid,
            new Callback<Building>() {
                @Override
                public void onSuccess(Building building) {
                    if (building == null) {
                        Toast.makeText(MainActivity.this, "No building", Toast.LENGTH_LONG)
                                .show();
                        return;
                    }

                    // ManagedProvider must be set after the map is loaded
                    ManagedProviderFactory.ManagedProviderFactoryBuilder builder =
                            new ManagedProviderFactory.ManagedProviderFactoryBuilder();
                    builder.application(getApplication())
                            .context(new WeakReference<Context>(getApplication()))
                            .venueId(String.valueOf(buildingId))
                            .slCustomerId(getString(R.string.pw_sl_customer_id))
                            .slMapKey(getString(R.string.pw_sl_map_id))
                            .bpOrgId(getString(R.string.pw_beacon_point_org_id));
                    ManagedProviderFactory factory = builder.build();
                    PwManagedLocationProvider provider = (PwManagedLocationProvider) factory
                            .createLocationProvider();
                    mapManager.setLocationProvider(provider, building);
						...

 

 


Step 6 - Enable Location Updates

Enable location updates after setting the map, building and provider



@Override
public void onPhunwareMapReady(final PhunwareMap phunwareMap) {
	...
    mapManager.addBuilding(buildingId, venueGuid,
            new Callback<Building>() {
                @Override
                public void onSuccess(Building building) {
					...
					// enable my location (blue dot) after setting the location provider
					mapManager.setMyLocationEnabled(true);

					}

				}

}

 

 


Step 7 - Manage Location Updates when in the Background

In order to ensure that lifecycles are managed correctly, stop location updates must not be requested in the background.Updates must be requested in the foreground. 


@Override
protected void onPause() {
    super.onPause();
	

	// If you have permission to access location and you don't have a building then proceed

	if (canAccessLocation() && building == null) {
    	if (mapFragment != null) {
        	mapFragment.getPhunwareMapAsync(this);
    	}
	}
    if (mapManager != null) {
        mapManager.setMyLocationEnabled(false);
    }
}
 
@Override
protected void onResume() {
    super.onResume();
 
    if (mapManager != null) {
        mapManager.setMyLocationEnabled(true);
    }
}

 

 

  • No labels