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 @@
-
@@ -23,31 +22,31 @@
-
+
+
-
+
-
+
-
@@ -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