diff --git a/MQSimpleAndroidMap.iml b/MQSimpleAndroidMap.iml new file mode 100644 index 0000000..2b8c676 --- /dev/null +++ b/MQSimpleAndroidMap.iml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/README.md b/README.md index 73d9a84..e50401d 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,15 @@ -# MQSimpleAndroidMap -Simple map using the MapQuest Android sdk +# MapQuest Maps SDK for Android + +This sample application is provided to show off some of the features of MapQuest's Map SDK. Please visit our [Getting Started Guide](https://developer.mapquest.com/documentation/maps-sdk/android/) for instructions on how to get up and running with the SDK. The Getting Started Guide walks you through the basics of getting a MapQuest API key, adding markers, customizing styles, and much more. + +This sample app is based off the Getting Started Guide and shows how to: +* Street, Night and Satellite Modes +* Adding Polygons/Polylines +* Adding Markers +* Using Search Ahead to show markers on the map +* Using Follow mode +* Using the Camera +* Toggle traffic +* Customizing styles + + diff --git a/app/app.iml b/app/app.iml index f9b7160..85bb5fb 100644 --- a/app/app.iml +++ b/app/app.iml @@ -9,7 +9,6 @@ - + + - + - + - @@ -55,122 +54,122 @@ - + + + + + + + - - - - - - - - - - + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + - + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 66230d3..1c1797b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,34 +1,96 @@ -apply plugin: 'com.android.application' - -android { - compileSdkVersion 24 - buildToolsVersion "23.0.3" - defaultConfig { - applicationId "com.example.mqbc.simplemap" - minSdkVersion 15 - targetSdkVersion 24 - versionCode 1 - versionName "1.0" - testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" - } - buildTypes { - release { - minifyEnabled false - proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' - } - } -} - -dependencies { - compile fileTree(dir: 'libs', include: ['*.jar']) - androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { - exclude group: 'com.android.support', module: 'support-annotations' - }) - compile 'com.android.support:appcompat-v7:24.2.1' - testCompile 'junit:junit:4.12' - - // added for MapQuest map - compile('com.mapquest:mapping-android-sdk:1.3.18@aar') { - transitive = true - } -} \ No newline at end of file +apply plugin: 'com.android.application' + +android { + def getKeystorePropertiesFile = { build -> + return new File("${rootDir}/app/keystore/${build}.properties") + } + + def getKeystoreProperties = { propertiesFile -> + def props = new Properties() + props.load(new FileInputStream(propertiesFile)) + return props + } + + compileSdkVersion 27 + buildToolsVersion '27.0.3' + + def defaultAppVersionCode = '1' + def appVersionCode = System.getProperty('versionCode', defaultAppVersionCode).toInteger() + + applicationVariants.all { variant -> + variant.buildConfigField "String", "API_KEY", getApiKey() + variant.resValue "string", "API_KEY", getApiKey() + } + + defaultConfig { + applicationId "com.mapquest.mapping.example" + minSdkVersion 16 + targetSdkVersion 27 + versionCode appVersionCode + versionName "2.0.9" + multiDexEnabled true + } + + signingConfigs { + release { + def properties = getKeystoreProperties(getKeystorePropertiesFile('release')) + storeFile = file(properties['storeFile']) + storePassword = properties['storePassword'] + keyAlias = properties['keyAlias'] + keyPassword = properties['keyPassword'] + } + } + + buildTypes { + debug { + applicationIdSuffix '.debug' + } + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + signingConfig signingConfigs.debug + } + } + + packagingOptions { + exclude 'META-INF/DEPENDENCIES.txt' + exclude 'META-INF/DEPENDENCIES' + exclude 'META-INF/dependencies.txt' + exclude 'META-INF/LICENSE.txt' + exclude 'META-INF/LICENSE' + exclude 'META-INF/license.txt' + exclude 'META-INF/NOTICE.txt' + exclude 'META-INF/NOTICE' + exclude 'META-INF/notice.txt' + exclude 'META-INF/LGPL2.1' + exclude 'META-INF/INDEX.LIST' + exclude 'LICENSE.txt' + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + + +dependencies { + testImplementation 'junit:junit:4.12' + implementation fileTree(include: ['*.jar'], dir: 'libs') + implementation 'com.android.support:appcompat-v7:27.1.1' + implementation 'com.google.android.gms:play-services-location:15.0.1' + implementation ('com.mapquest:searchahead:1.3.1') { + transitive = true + } + + implementation 'com.android.support:multidex:1.0.3' + + implementation("com.mapquest:mapping-android-sdk:2.0.9") + implementation 'com.android.support:design:27.1.1' +} + +def getApiKey() { + def props = new Properties() + file("mapquest.properties").withInputStream { props.load(it) } + return "\"" + props.getProperty("api_key") + "\"" +} + diff --git a/app/keystore/release.properties b/app/keystore/release.properties new file mode 100644 index 0000000..33d8000 --- /dev/null +++ b/app/keystore/release.properties @@ -0,0 +1,4 @@ +storeFile=../app/keystore/release.keystore +keyAlias=androidreleasekey +storePassword=android +keyPassword=android \ No newline at end of file diff --git a/app/mapquest.properties b/app/mapquest.properties new file mode 100644 index 0000000..5cedbbe --- /dev/null +++ b/app/mapquest.properties @@ -0,0 +1 @@ +api_key= diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 0ea79bf..68e5693 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -1,17 +1,17 @@ -# Add project specific ProGuard rules here. -# By default, the flags in this file are appended to flags specified -# in C:\Users\briancoakley07\AppData\Local\Android\sdk/tools/proguard/proguard-android.txt -# You can edit the include path and order by changing the proguardFiles -# directive in build.gradle. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html - -# Add any project specific keep options here: - -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in /Applications/Android/sdk/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the proguardFiles +# directive in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 9a801a1..43e451b 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,17 +1,18 @@ - - - - - - - - - - - \ No newline at end of file + + + + + + + + + + + + + + + + diff --git a/app/src/main/java/com/example/mqbc/apihook/MainActivity.java b/app/src/main/java/com/example/mqbc/apihook/MainActivity.java deleted file mode 100644 index e315771..0000000 --- a/app/src/main/java/com/example/mqbc/apihook/MainActivity.java +++ /dev/null @@ -1,172 +0,0 @@ -package com.example.mqbc.apihook; - -import android.graphics.Color; -import android.os.AsyncTask; -import android.support.v7.app.AppCompatActivity; -import android.os.Bundle; - -import com.mapbox.mapboxsdk.annotations.PolylineOptions; -import com.mapbox.mapboxsdk.camera.CameraUpdateFactory; -import com.mapbox.mapboxsdk.geometry.LatLng; -import com.mapbox.mapboxsdk.geometry.LatLngBounds; -import com.mapquest.mapping.maps.MapboxMap; -import com.mapquest.mapping.maps.OnMapReadyCallback; -import com.mapquest.mapping.MapQuestAccountManager; -import com.mapquest.mapping.maps.MapView; - -import org.json.JSONArray; -import org.json.JSONObject; - -import java.io.BufferedReader; -import java.io.InputStreamReader; -import java.net.HttpURLConnection; -import java.net.URL; -import java.net.URLEncoder; -import java.util.ArrayList; -import java.util.List; - -public class MainActivity extends AppCompatActivity { - private MapView mapView; - private MapboxMap map; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - MapQuestAccountManager.start(getApplicationContext()); - setContentView(R.layout.activity_main); - mapView = (MapView) findViewById(R.id.mapquestMapView); - mapView.onCreate(savedInstanceState); - mapView.getMapAsync(new OnMapReadyCallback() { - @Override - public void onMapReady(MapboxMap mapboxMap) { - map = mapboxMap; - Route route = new Route(); - route.execute( - "1555 Blake St, Denver, CO", // origin - "39.744979,-104.989506", // destination - "pedestrian" // type - ); - } - }); - } - - private class Route extends AsyncTask { - protected String doInBackground(String... args){ - JSONObject postData = new JSONObject(); - try { - // JSONArray of start and finish - JSONArray locations = new JSONArray(); - locations.put(URLEncoder.encode(args[0], "UTF-8")); - locations.put(URLEncoder.encode(args[1], "UTF-8")); - postData.put("locations", locations); // put array inside main object - - // JSONObject options - JSONObject options = new JSONObject(); - options.put("routeType", args[2]); - options.put("generalize", "0"); - postData.put("options", options); - } - catch (Exception e) { - e.printStackTrace(); - } - - // create the api request string - String urlstring = "http://www.mapquestapi.com/directions/v2/route" + - "?key=brK53YAgFqbRjCvs7rlH65HqS1GGVAlK&json=" + - postData.toString(); - - // make the GET request and prep the response string - StringBuilder json = new StringBuilder(); - try { - URL url = new URL(urlstring); - HttpURLConnection urlConn = (HttpURLConnection) url.openConnection(); - try { - BufferedReader rd = new BufferedReader(new InputStreamReader(urlConn.getInputStream())); - String line; - while ((line = rd.readLine()) != null) { - json.append(line); - } - } catch (Exception e) { - System.out.println("catch B: " + e.toString()); - } finally { - urlConn.disconnect(); - } - } catch (Exception e) { - System.out.println("catch C: " + e.toString()); - } - return json.toString(); - } - - protected void onPostExecute(String json){ - try { - // get shape points from response - JSONArray points = new JSONObject(json) - .getJSONObject("route") - .getJSONObject("shape") - .getJSONArray("shapePoints"); - - // get every other shape point - int pointcount = points.length() / 2; - - // create a shape point list - List shapePoints = new ArrayList<>(); - - // fill list with every even value as lat and odd value as lng - for (int point = 0; point < pointcount; point = point + 1) { - shapePoints.add(new LatLng( - (double) points.get(point * 2), - (double) points.get(point * 2 + 1) - )); - } - - // create polyline options - PolylineOptions polyline = new PolylineOptions(); - polyline.addAll(shapePoints) - .width(5) - .color(Color.GRAY) - .alpha((float)0.75); - - // add the polyline to the map - map.addPolyline(polyline); - - // get map bounds - JSONObject bounds = new JSONObject(json) - .getJSONObject("route") - .getJSONObject("boundingBox"); - - // create bounds for animating map - LatLngBounds latLngBounds = new LatLngBounds.Builder() - .include(new LatLng( - (double) bounds.getJSONObject("ul").get("lat"), - (double) bounds.getJSONObject("ul").get("lng") - )) - .include(new LatLng( - (double) bounds.getJSONObject("lr").get("lat"), - (double) bounds.getJSONObject("lr").get("lng") - )) - .build(); - - // animate to map bounds - map.animateCamera(CameraUpdateFactory.newLatLngBounds(latLngBounds, 50), 5000); - } catch (Exception e) { - System.out.println("catch D: " + e.toString()); - } - } - } - - @Override - public void onResume() - { super.onResume(); mapView.onResume(); } - - @Override - public void onPause() - { super.onPause(); mapView.onPause(); } - - @Override - protected void onDestroy() - { super.onDestroy(); mapView.onDestroy(); } - - @Override - protected void onSaveInstanceState(Bundle outState) - { super.onSaveInstanceState(outState); mapView.onSaveInstanceState(outState); } -} \ No newline at end of file diff --git a/app/src/main/java/com/example/mqbc/apihook/README b/app/src/main/java/com/example/mqbc/apihook/README deleted file mode 100644 index 8526656..0000000 --- a/app/src/main/java/com/example/mqbc/apihook/README +++ /dev/null @@ -1 +0,0 @@ -This sample shows how to hit the MapQuest directions api and put the resulting route highlight on the map. diff --git a/app/src/main/java/com/example/mqbc/mapbasics/MainActivity.java b/app/src/main/java/com/example/mqbc/mapbasics/MainActivity.java deleted file mode 100644 index f0a03ee..0000000 --- a/app/src/main/java/com/example/mqbc/mapbasics/MainActivity.java +++ /dev/null @@ -1,68 +0,0 @@ -package com.example.mqbc.mapbasics; - -import android.support.v7.app.AppCompatActivity; -import android.os.Bundle; -import com.mapbox.mapboxsdk.annotations.MarkerOptions; -import com.mapbox.mapboxsdk.camera.CameraUpdateFactory; -import com.mapquest.mapping.maps.MapboxMap; -import com.mapbox.mapboxsdk.geometry.LatLng; -import com.mapquest.mapping.MapQuestAccountManager; -import com.mapquest.mapping.constants.Style; -import com.mapquest.mapping.maps.MapView; -import com.mapquest.mapping.maps.OnMapReadyCallback; - -public class MainActivity extends AppCompatActivity { - private MapboxMap map; - private MapView mapView; - private final LatLng SAN_FRAN = new LatLng(37.7749, -122.4194); - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_main); - - MapQuestAccountManager.start(getApplicationContext()); - mapView = (MapView) findViewById(R.id.mapquestMapView); - mapView.onCreate(savedInstanceState); - - mapView.getMapAsync(new OnMapReadyCallback() { - @Override - public void onMapReady(MapboxMap mapboxMap) { - map = mapboxMap; - - // create and add marker - MarkerOptions markerOptions = new MarkerOptions(); - markerOptions.position(SAN_FRAN); - markerOptions.title("San Francisco"); - markerOptions.snippet("Welcome to Frisco!"); - map.addMarker(markerOptions); - - // set map center and zoom - map.moveCamera(CameraUpdateFactory.newLatLngZoom(SAN_FRAN, 14)); - - // turn on traffic - map.setTrafficFlowLayerOn(); - map.setTrafficIncidentLayerOn(); - - // set map style - mapView.setStyleUrl(Style.MAPQUEST_SATELLITE); - } - }); - } - - @Override - public void onResume() - { super.onResume(); mapView.onResume(); } - - @Override - public void onPause() - { super.onPause(); mapView.onPause(); } - - @Override - protected void onDestroy() - { super.onDestroy(); mapView.onDestroy(); } - - @Override - protected void onSaveInstanceState(Bundle outState) - { super.onSaveInstanceState(outState); mapView.onSaveInstanceState(outState); } -} \ No newline at end of file diff --git a/app/src/main/java/com/example/mqbc/mapbasics/README b/app/src/main/java/com/example/mqbc/mapbasics/README deleted file mode 100644 index dc92d02..0000000 --- a/app/src/main/java/com/example/mqbc/mapbasics/README +++ /dev/null @@ -1 +0,0 @@ -Simple map with basic functionality like setting zoom, center, and style and putting a marker on the map. diff --git a/app/src/main/java/com/example/mqbc/simplemap/MainActivity.java b/app/src/main/java/com/example/mqbc/simplemap/MainActivity.java deleted file mode 100644 index 6a40d87..0000000 --- a/app/src/main/java/com/example/mqbc/simplemap/MainActivity.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.example.mqbc.simplemap; - -import android.support.v7.app.AppCompatActivity; -import android.os.Bundle; -import com.mapbox.mapboxsdk.MapboxAccountManager; -import com.mapquest.mapping.maps.MapView; - -public class MainActivity extends AppCompatActivity { - private MapView mapView; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - MapboxAccountManager.start(getApplicationContext()); - setContentView(R.layout.activity_main); - mapView = (MapView) findViewById(R.id.mapquestMapView); - mapView.onCreate(savedInstanceState); - } - - @Override - public void onResume() { - super.onResume(); - mapView.onResume(); - } - - @Override - public void onPause() { - super.onPause(); - mapView.onPause(); - } - - @Override - protected void onDestroy() { - super.onDestroy(); - mapView.onDestroy(); - } - - @Override - protected void onSaveInstanceState(Bundle outState) { - super.onSaveInstanceState(outState); - mapView.onSaveInstanceState(outState); - } -} \ No newline at end of file diff --git a/app/src/main/java/com/mapquest/mapping/example/MBLatLngUtil.java b/app/src/main/java/com/mapquest/mapping/example/MBLatLngUtil.java new file mode 100644 index 0000000..e337911 --- /dev/null +++ b/app/src/main/java/com/mapquest/mapping/example/MBLatLngUtil.java @@ -0,0 +1,10 @@ +package com.mapquest.mapping.example; + +import com.mapbox.mapboxsdk.geometry.LatLng; + +public final class MBLatLngUtil extends LatLng { + + static LatLng fromMQLatLng(com.mapquest.android.commoncore.model.LatLng latLng) { + return new LatLng((double)latLng.getLatitude(), (double)latLng.getLongitude()); + } +} diff --git a/app/src/main/java/com/mapquest/mapping/example/MQLatLng.java b/app/src/main/java/com/mapquest/mapping/example/MQLatLng.java new file mode 100644 index 0000000..26c15ef --- /dev/null +++ b/app/src/main/java/com/mapquest/mapping/example/MQLatLng.java @@ -0,0 +1,11 @@ +package com.mapquest.mapping.example; + +import android.location.Location; + +public final class MQLatLng extends com.mapquest.android.commoncore.model.LatLng { + + public MQLatLng(Location location) { + super((float)location.getLatitude(), (float)location.getLongitude()); + } + +} diff --git a/app/src/main/java/com/mapquest/mapping/example/MainActivity.java b/app/src/main/java/com/mapquest/mapping/example/MainActivity.java new file mode 100644 index 0000000..3b68e08 --- /dev/null +++ b/app/src/main/java/com/mapquest/mapping/example/MainActivity.java @@ -0,0 +1,461 @@ +package com.mapquest.mapping.example; + +import android.annotation.SuppressLint; +import android.graphics.Bitmap; +import android.graphics.Color; +import android.location.Location; +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.Toolbar; +import android.view.Menu; +import android.view.MenuItem; +import android.widget.Toast; + +import com.google.android.gms.location.FusedLocationProviderClient; +import com.google.android.gms.location.LocationCallback; +import com.google.android.gms.location.LocationRequest; +import com.google.android.gms.location.LocationResult; +import com.google.android.gms.location.LocationServices; +import com.mapbox.android.core.permissions.PermissionsListener; +import com.mapbox.android.core.permissions.PermissionsManager; +import com.mapbox.mapboxsdk.annotations.IconFactory; +import com.mapbox.mapboxsdk.annotations.Marker; +import com.mapbox.mapboxsdk.annotations.MarkerOptions; +import com.mapbox.mapboxsdk.annotations.PolygonOptions; +import com.mapbox.mapboxsdk.annotations.PolylineOptions; +import com.mapbox.mapboxsdk.camera.CameraUpdateFactory; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.style.layers.FillLayer; +import com.mapbox.mapboxsdk.style.layers.PropertyFactory; +import com.mapquest.android.commoncore.log.L; +import com.mapquest.android.searchahead.IllegalQueryParameterException; +import com.mapquest.android.searchahead.SearchAheadService; +import com.mapquest.android.searchahead.model.SearchAheadQuery; +import com.mapquest.android.searchahead.model.SearchCollection; +import com.mapquest.android.searchahead.model.response.AddressProperties; +import com.mapquest.android.searchahead.model.response.Place; +import com.mapquest.android.searchahead.model.response.SearchAheadResponse; +import com.mapquest.android.searchahead.model.response.SearchAheadResult; +import com.mapquest.mapping.MapQuest; +import com.mapquest.mapping.maps.MapView; +import com.mapquest.mapping.maps.MapboxMapTrafficPresenter; +import com.mapquest.mapping.maps.MyLocationPresenter; +import com.mapquest.mapping.utils.PoiOnMapData; + +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class MainActivity extends AppCompatActivity { + private static final float DEFAULT_ZOOM_LEVEL = 12; + private static final LatLng MAPQUEST_HEADQUARTERS_LOCATION = new LatLng(39.750307, -104.999472); + private static final double FOLLOW_MODE_TILT_VALUE_DEGREES = 50; + private static final double CENTER_ON_USER_ZOOM_LEVEL = 18; + private MapView mMapView; + private MapboxMap mMapboxMap; + private MapboxMapTrafficPresenter mMapboxMapTrafficPresenter; + private boolean mTrafficFlag; + private MyLocationPresenter locationPresenter; + private FusedLocationProviderClient mFusedLocationClient; + private PermissionsManager permissionsManager; + private LocationCallback mLocationCallback; + private LocationRequest mLocationRequest; + private SearchAheadService mSearchAheadServiceV3; + private List mPOIMarkers = new ArrayList<>(); + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + MapQuest.start(getApplicationContext()); + setContentView(R.layout.activity_main); + + mTrafficFlag = false; + + Toolbar myToolbar = findViewById(R.id.my_toolbar); + setSupportActionBar(myToolbar); + + mMapView = findViewById(R.id.mapquestMapView); + + mMapView.onCreate(savedInstanceState); + mMapView.getMapAsync(mapboxMap -> { + mMapboxMap = mapboxMap; + mMapboxMapTrafficPresenter = new MapboxMapTrafficPresenter(mMapboxMap, mMapView); + + mMapView.setPOIOnMapSelectedListener(poiOnMapList -> { + PoiOnMapData selectedPOI = poiOnMapList.get(0); + showMarkerForPOI(selectedPOI); + }); + +// // This is the way to set style changes to your map on style load +// mMapView.addOnMapChangedListener(change -> { +// if (change == DID_FINISH_LOADING_STYLE) { +// FillLayer fillLayer = (FillLayer) mMapboxMap.getLayer("building"); +// if (fillLayer != null) { +// fillLayer.setProperties( +// PropertyFactory.fillColor(Color.RED) +// ); +// } +// } +// }); + }); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.main, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.street_view: + mMapView.setStreetMode(); + return true; + case R.id.satellite_view: + mMapView.setSatelliteMode(); + return true; + case R.id.night_view: + mMapView.setNightMode(); + return true; + case R.id.add_polygon: + setPolygon(mMapboxMap); + return true; + case R.id.add_polyline: + setPolyline(mMapboxMap); + return true; + case R.id.add_annotation: + addMarker(mMapboxMap); + return true; + case R.id.goto_Denver: + initializeMapView(mMapView, mMapboxMap); + return true; + case R.id.goto_user_loc: + enableUserTracking(mMapView, mMapboxMap); + return true; + case R.id.toggle_traffic: + if (mTrafficFlag) { + mMapboxMapTrafficPresenter.setTrafficFlowLayerOff(); + mMapboxMapTrafficPresenter.setTrafficIncidentLayerOff(); + } else { + mMapboxMapTrafficPresenter.setTrafficFlowLayerOn(); + mMapboxMapTrafficPresenter.setTrafficIncidentLayerOn(); + } + mTrafficFlag = !mTrafficFlag; + return true; + case R.id.styleBuildings: + setBuildingsRed(mMapboxMap); + return true; + + case R.id.add_coffeeshops: + searchCoffeeShops(); + return true; + default: + return super.onOptionsItemSelected(item); + } + } + + private void showMarkerForPOI(PoiOnMapData selectedPOI) { + //Make a transparent marker + Bitmap.Config conf = Bitmap.Config.ARGB_8888; // see other conf types + Bitmap transparent = Bitmap.createBitmap(1, 1, conf); // this creates a transparent bitmap + + IconFactory iconFactory = IconFactory.getInstance(MainActivity.this); + + MarkerOptions markerOptions = new MarkerOptions(); + markerOptions.position(MBLatLngUtil.fromMQLatLng(selectedPOI.getLatLng())); + markerOptions.title(selectedPOI.getName()); + markerOptions.setIcon(iconFactory.fromBitmap(transparent)); + + for (Marker marker : mPOIMarkers) { + mMapboxMap.removeMarker(marker); + } + + Marker marker = mMapboxMap.addMarker(markerOptions); + mPOIMarkers.add(marker); + mMapboxMap.selectMarker(marker); + } + + private void setBuildingsRed(MapboxMap mapboxMap) { + FillLayer fillLayer = (FillLayer) mapboxMap.getLayer("building"); + if (fillLayer != null) { + fillLayer.setProperties( + PropertyFactory.fillColor(Color.RED) + ); + } + } + + private void setPolyline(MapboxMap mapboxMap) { + + LatLng CAMERA_LOC = new LatLng(39.745391, -105.00653); + mMapView.setStreetMode(); + mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(CAMERA_LOC, 13)); + + List coordinates = new ArrayList<>(); + + coordinates.add(new LatLng(39.74335,-105.01234)); + coordinates.add(new LatLng(39.74667,-105.01135)); + coordinates.add(new LatLng(39.7468,-105.00709)); + coordinates.add(new LatLng(39.74391,-105.00794)); + coordinates.add(new LatLng(39.7425,-105.0047)); + coordinates.add(new LatLng(39.74634,-105.00478)); + coordinates.add(new LatLng(39.74734,-104.99984)); + + PolylineOptions polyline = new PolylineOptions(); + polyline.addAll(coordinates); + polyline.width(3); + polyline.color(Color.BLUE); + mapboxMap.addPolyline(polyline); + } + + private void setPolygon(MapboxMap mapboxMap) { + LatLng CAMERA_LOC = new LatLng(39.743943, -105.020089); + mMapView.setStreetMode(); + mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(CAMERA_LOC, 15)); + + List coordinates = new ArrayList<>(); + coordinates.add(new LatLng(39.744465080845458,-105.02038957961648)); + coordinates.add(new LatLng(39.744460864711129,-105.01981090977684)); + coordinates.add(new LatLng(39.744379574636383,-105.01970518778262)); + coordinates.add(new LatLng(39.743502042120781,-105.01970874744497)); + coordinates.add(new LatLng(39.743419794549339,-105.01977839958302)); + coordinates.add(new LatLng(39.74341214360723,-105.02038412442006)); + coordinates.add(new LatLng(39.74349726029007,-105.02049233399056)); + coordinates.add(new LatLng(39.744393745651706,-105.0204836274754)); + + PolygonOptions polygon = new PolygonOptions(); + polygon.addAll(coordinates); + polygon.fillColor(Color.rgb(255, 102, 0)); + polygon.strokeColor(Color.BLACK); + mapboxMap.addPolygon(polygon); + } + + private void addMarker(MapboxMap mapboxMap) { + initializeMapView(mMapView, mapboxMap); + MarkerOptions markerOptions = new MarkerOptions(); + markerOptions.position(MAPQUEST_HEADQUARTERS_LOCATION); + markerOptions.title("MapQuest"); + markerOptions.snippet("Welcome to Denver!"); + mapboxMap.addMarker(markerOptions); + + mapboxMap.setOnMarkerClickListener(marker -> { + Toast.makeText(MainActivity.this, marker.getTitle(), Toast.LENGTH_LONG).show(); + return true; + }); + } + + @SuppressWarnings( {"MissingPermission"}) + private void initializeLocationEngine(Runnable success) { + + // Check if permissions are enabled and if not request + if (PermissionsManager.areLocationPermissionsGranted(this)) { + success.run(); + } else { + permissionsManager = new PermissionsManager(new PermissionsListener() { + + @Override + public void onExplanationNeeded(List permissionsToExplain) { + // Left blank on purpose + } + + @Override + public void onPermissionResult(boolean granted) { + if (granted) { + success.run(); + } + } + + }); + permissionsManager.requestLocationPermissions(this); + } + } + + @SuppressLint("MissingPermission") + private void setupLocationEngine(LocationCallback locationCallback) { + + mLocationRequest = new LocationRequest(); + mLocationRequest.setInterval(1000); + mLocationRequest.setFastestInterval(1000); + mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); + + if (mLocationCallback != null && mFusedLocationClient != null) { + mFusedLocationClient.removeLocationUpdates(mLocationCallback); + } else if (mFusedLocationClient == null) { + mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this); + } + + mLocationCallback = locationCallback; + mFusedLocationClient.requestLocationUpdates(mLocationRequest, mLocationCallback, null); + } + + private void cleanupLocationEngine() { + mFusedLocationClient.removeLocationUpdates(mLocationCallback); + mLocationRequest = null; + mLocationCallback = null; + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + permissionsManager.onRequestPermissionsResult(requestCode, permissions, grantResults); + } + + private void enableUserTracking(MapView mapView, MapboxMap mapboxMap) { + + initializeLocationEngine(() -> { + setupLocationPresenter(mapView, mapboxMap); + setupLocationEngine( new LocationCallback() { + @Override + public void onLocationResult(LocationResult locationResult) { + if (locationResult == null) { + return; + } + for (Location location : locationResult.getLocations()) { + locationPresenter.forceLocationChange(location); + } + } + + }); + }); + } + + private void setupLocationPresenter(MapView mapView, MapboxMap mapboxMap) { + + if (locationPresenter == null) { + locationPresenter = new MyLocationPresenter(mapView, mapboxMap, null); + } + + locationPresenter.setInitialZoomLevel(CENTER_ON_USER_ZOOM_LEVEL); + locationPresenter.setFollowCameraAngle(FOLLOW_MODE_TILT_VALUE_DEGREES); + locationPresenter.setLockNorthUp(false); + locationPresenter.setFollow(true); + locationPresenter.onStart(); + } + + private void initializeMapView(MapView mapView, MapboxMap mapboxMap) { + mapView.setStreetMode(); + mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(MAPQUEST_HEADQUARTERS_LOCATION, DEFAULT_ZOOM_LEVEL)); + } + + private void searchCoffeeShops() { + + initializeLocationEngine(() -> { + setupLocationEngine( new LocationCallback() { + @Override + public void onLocationResult(LocationResult locationResult) { + if (locationResult == null) { + return; + } + + cleanupLocationEngine(); + performSearch("coffee", locationResult); + } + + }); + }); + } + + private void performSearch(String queryString, LocationResult locationResult) { + + Location lastLocation = locationResult.getLastLocation(); + mMapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(lastLocation.getLatitude(), lastLocation.getLongitude()), 10)); + + if (mSearchAheadServiceV3 == null) { + mSearchAheadServiceV3 = new SearchAheadService(this, BuildConfig.API_KEY); + } + + List searchCollections = Collections.singletonList(SearchCollection.POI); + try { + MQLatLng latLng = new MQLatLng(lastLocation); + + SearchAheadQuery query = new SearchAheadQuery.Builder(queryString, searchCollections).location(latLng).build(); + mSearchAheadServiceV3.predictResultsFromQuery(query, + new SearchAheadService.SearchAheadResponseCallback() { + + @Override + public void onSuccess(@NonNull SearchAheadResponse searchAheadResponse) { + + MainActivity.this.runOnUiThread(() -> { + for (SearchAheadResult result : searchAheadResponse.getResults()) { + MarkerOptions markerOptions = new MarkerOptions(); + Place place = result.getPlace(); + AddressProperties aProp = place.getAddressProperties(); + + String address = new StringBuilder() + .append(StringUtils.defaultIfEmpty(aProp.getStreet(), "")).append("\n") + .append(StringUtils.defaultIfEmpty(aProp.getCity(), "")).append(" ") + .append(StringUtils.defaultIfEmpty(aProp.getStateCode(), "")).append( " ") + .append(StringUtils.defaultIfEmpty(aProp.getPostalCode(), "")).append("\n") + .toString(); + markerOptions.position( MBLatLngUtil.fromMQLatLng( place.getLatLng() ) ); + markerOptions.title(result.getDisplayString()); + markerOptions.snippet(address); + mMapboxMap.addMarker(markerOptions); + } + }); + } + + @Override + public void onError(Exception e) { + L.e("Search Ahead V3 Failure", e); + } + }); + } catch (IllegalQueryParameterException e) { + L.e("Error performing search", e); + } + } + + @Override + protected void onStart() { + super.onStart(); + mMapView.onStart(); + } + + @Override + protected void onStop() { + super.onStop(); + mMapView.onStop(); + } + + @SuppressLint("MissingPermission") + @Override + public void onResume() { + super.onResume(); + mMapView.onResume(); + if (mFusedLocationClient != null) { + mFusedLocationClient.requestLocationUpdates(mLocationRequest, mLocationCallback, null); + } + + if (locationPresenter != null) { + locationPresenter.onStart(); + } + } + + @Override + public void onPause() { + super.onPause(); + mMapView.onPause(); + if (mFusedLocationClient != null) { + mFusedLocationClient.removeLocationUpdates(mLocationCallback); + } + if (locationPresenter != null) { + locationPresenter.onStop(); + } + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mMapView.onDestroy(); + } + + @Override + protected void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + mMapView.onSaveInstanceState(outState); + } + +} diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index e1150a6..f2f9565 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -1,21 +1,22 @@ - - - - - - + + + + + + diff --git a/app/src/main/res/menu/main.xml b/app/src/main/res/menu/main.xml new file mode 100644 index 0000000..8b53fbe --- /dev/null +++ b/app/src/main/res/menu/main.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml new file mode 100644 index 0000000..99764b6 --- /dev/null +++ b/app/src/main/res/values/dimens.xml @@ -0,0 +1,6 @@ + + + 5dp + 5dp + 100dp + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml new file mode 100644 index 0000000..6a5b89b --- /dev/null +++ b/app/src/main/res/values/strings.xml @@ -0,0 +1,9 @@ + + MapQuest Mapping SDK Example + Streets + Satellite + Traffic Flow + Traffic Incidents + Click on menu for Menu Demo + + diff --git a/build.gradle b/build.gradle index 92cf142..b7f4eba 100644 --- a/build.gradle +++ b/build.gradle @@ -1,23 +1,33 @@ -// Top-level build file where you can add configuration options common to all sub-projects/modules. - -buildscript { - repositories { - jcenter() - } - dependencies { - classpath 'com.android.tools.build:gradle:2.2.3' - } -} - -allprojects { - repositories { - jcenter() - - // added for MapQuest map - maven {url 'http://artifactory.cloud.mapquest.com/artifactory/et-android-binaries'} - } -} - -task clean(type: Delete) { - delete rootProject.buildDir -} +// Top-level build file where you can add configuration options common to all sub-projects/modules. +apply plugin: 'com.jfrog.artifactory' +apply plugin: 'maven-publish' + +buildscript { + repositories { + jcenter() + google() + } + dependencies { + // NOTE: Do not place your application dependencies here; they belong + // in the individual module build.gradle files + classpath 'com.android.tools.build:gradle:3.1.2' + classpath 'com.jakewharton.sdkmanager:gradle-plugin:0.12.0' + classpath 'org.jfrog.buildinfo:build-info-extractor-gradle:4.3.0' + } +} + +allprojects { + repositories { + jcenter() + // NOTE: this is the public repo for the MapQuest Navigation SDK + maven { + url "https://artifactory.cloud.mapquest.com/artifactory/et-android-binaries" + } + google() + } +} + + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/gradlew b/gradlew index 9d82f78..cccdd3d 100644 --- a/gradlew +++ b/gradlew @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +#!/usr/bin/env sh ############################################################################## ## @@ -6,20 +6,38 @@ ## ############################################################################## -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null APP_NAME="Gradle" APP_BASE_NAME=`basename "$0"` +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD="maximum" -warn ( ) { +warn () { echo "$*" } -die ( ) { +die () { echo echo "$*" echo @@ -30,6 +48,7 @@ die ( ) { cygwin=false msys=false darwin=false +nonstop=false case "`uname`" in CYGWIN* ) cygwin=true @@ -40,26 +59,11 @@ case "`uname`" in MINGW* ) msys=true ;; + NONSTOP* ) + nonstop=true + ;; esac -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null - CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -85,7 +89,7 @@ location of your Java installation." fi # Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then MAX_FD_LIMIT=`ulimit -H -n` if [ $? -eq 0 ] ; then if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then @@ -150,11 +154,19 @@ if $cygwin ; then esac fi -# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules -function splitJvmOpts() { - JVM_OPTS=("$@") +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " } -eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS -JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi -exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat index aec9973..e95643d 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -8,14 +8,14 @@ @rem Set local scope for the variables with windows NT shell if "%OS%"=="Windows_NT" setlocal -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= - set DIRNAME=%~dp0 if "%DIRNAME%" == "" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome @@ -46,10 +46,9 @@ echo location of your Java installation. goto fail :init -@rem Get command-line arguments, handling Windowz variants +@rem Get command-line arguments, handling Windows variants if not "%OS%" == "Windows_NT" goto win9xME_args -if "%@eval[2+2]" == "4" goto 4NT_args :win9xME_args @rem Slurp the command line arguments. @@ -60,11 +59,6 @@ set _SKIP=2 if "x%~1" == "x" goto execute set CMD_LINE_ARGS=%* -goto execute - -:4NT_args -@rem Get arguments from the 4NT Shell from JP Software -set CMD_LINE_ARGS=%$ :execute @rem Setup the command line diff --git a/local.properties b/local.properties new file mode 100644 index 0000000..7f7faa2 --- /dev/null +++ b/local.properties @@ -0,0 +1,8 @@ +## This file must *NOT* be checked into Version Control Systems, +# as it contains information specific to your local configuration. +# +# Location of the SDK. This is only used by Gradle. +# For customization when using a Version Control System, please read the +# header note. +#Wed Jul 11 09:30:26 MDT 2018 +sdk.dir=/Users/akac60/Library/Android/sdk