// MapQuest extension for App Inventor by Marco Perrone package MapQuest; import com.google.appinventor.components.runtime.*; import android.app.Activity; import android.content.Intent; import com.google.appinventor.components.annotations.DesignerComponent; import com.google.appinventor.components.annotations.DesignerProperty; import com.google.appinventor.components.annotations.PropertyCategory; import com.google.appinventor.components.annotations.SimpleFunction; import com.google.appinventor.components.annotations.SimpleEvent; import com.google.appinventor.components.annotations.SimpleObject; import com.google.appinventor.components.annotations.SimpleProperty; import com.google.appinventor.components.annotations.UsesPermissions; import com.google.appinventor.components.annotations.UsesActivities; import com.google.appinventor.components.annotations.UsesLibraries; import com.google.appinventor.components.annotations.UsesActivityMetadata; import com.google.appinventor.components.annotations.androidmanifest.*; import com.google.appinventor.components.common.ComponentCategory; import com.google.appinventor.components.common.PropertyTypeConstants; import com.google.appinventor.components.common.YaVersion; import com.google.appinventor.components.runtime.util.GingerbreadUtil; import com.google.appinventor.components.runtime.util.SdkLevel; import com.google.appinventor.components.runtime.util.AsynchUtil; import com.google.appinventor.components.runtime.util.YailList; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLConnection; import java.net.URI; import java.net.URISyntaxException; import java.net.CookieHandler; import java.util.Scanner; import java.util.Iterator; import java.util.Map; import java.util.List; import java.util.ArrayList; import java.io.FileWriter; import java.io.BufferedWriter; import java.io.StringWriter; import java.io.PrintWriter; import java.io.IOException; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.io.InputStreamReader; import java.io.DataOutputStream; import java.io.BufferedReader; import java.io.OutputStream; @SimpleObject(external=true) @UsesPermissions(permissionNames = "android.permission.INTERNET,android.permission.READ_EXTERNAL_STORAGE,android.permission.WRITE_EXTERNAL_STORAGE") @DesignerComponent(version = YaVersion.WEB_COMPONENT_VERSION, description = "

Non-visible MapQuest component to get Route, Geocode, Reverse Geocode, Search POI.", category = ComponentCategory.EXTENSION, nonVisible = true, iconName = "images/nearfield.png") public class MapQuest extends AndroidNonvisibleComponent implements Component { private final Activity activity; private final CookieHandler cookieHandler; private String twoHyphens = "--"; private String boundary = "*****"+Long.toString(System.currentTimeMillis())+"*****"; private String LINE = "\r\n"; private URL url; private HttpURLConnection httpConn = null; private OutputStream outputStream; private PrintWriter writer; private String charset = "utf-8"; @SimpleEvent(description = "Got MapQuest Route Response") public void GotRoute(int responseCode, String response, YailList directions, YailList lat, YailList lon, YailList mapUrl, String distance, String message) { EventDispatcher.dispatchEvent(this, "GotRoute", responseCode, response, directions, lat, lon, mapUrl, distance, message); } @SimpleEvent(description = "Got MapQuest Geocode Response") public void GotGeocode(int responseCode, String response, YailList lat, YailList lon, YailList mapUrl, String message) { EventDispatcher.dispatchEvent(this, "GotGeocode", responseCode, response, lat, lon, mapUrl, message); } @SimpleEvent(description = "Got MapQuest Reverse Geocode Response") public void GotReverseGeocode(int responseCode, String response, String address, String mapUrl, String message) { EventDispatcher.dispatchEvent(this, "GotReverseGeocode", responseCode, response, address, mapUrl, message); } @SimpleEvent(description = "Got MapQuest Place Search Response") public void GotPlaceSearch(int responseCode, String response, YailList lat, YailList lon, YailList address, String message) { EventDispatcher.dispatchEvent(this, "GotPlaceSearch", responseCode, response, lat, lon, address, message); } @SimpleFunction(description = "Calculate Route") public void CalculateRoute(final String apiKey, final String from, final String to, final String unit, final String routeType, final String language) { AsynchUtil.runAsynchronously(new Runnable() { @Override public void run() { CalculateRoute_Exec(apiKey, from, to, unit, routeType, language); } }); } @SimpleFunction(description = "Geocode, finding an associated latitude and longitude for a given address") public void Geocode(final String apiKey, final String location) { AsynchUtil.runAsynchronously(new Runnable() { @Override public void run() { Geocode_Exec(apiKey, location); } }); } @SimpleFunction(description = "Reverse Geocode, the reverse geocoding service allows a latitude and longitude to be converted to a location") public void ReverseGeocode(final String apiKey, final String latitude, final String longitude) { AsynchUtil.runAsynchronously(new Runnable() { @Override public void run() { ReverseGeocode_Exec(apiKey, latitude, longitude); } }); } @SimpleFunction(description = "Place Search is a spatially-aware search engine most commonly used to return Point of Interest") public void PlaceSearch(final String apiKey, final String latitude, final String longitude, final String sort, final String radius, final String poi ) { AsynchUtil.runAsynchronously(new Runnable() { @Override public void run() { PlaceSearch_Exec(apiKey, latitude, longitude,sort, radius, poi); } }); } public MapQuest(ComponentContainer container) { super(container.$form()); activity = container.$context(); cookieHandler = (SdkLevel.getLevel() >= SdkLevel.LEVEL_GINGERBREAD) ? GingerbreadUtil.newCookieManager() : null; } void CalculateRoute_Exec(String APIKEY, String FROM, String TO, String UNIT, String ROUTETYPE, String LANGUAGE) { try { InputStream inputStream = null; String URLStr = "http://www.mapquestapi.com/directions/v2/route"; URLStr = URLStr + "?key=" + APIKEY; URLStr = URLStr + "&from=" + FROM; URLStr = URLStr + "&to=" + TO; URLStr = URLStr + "&unit=" + UNIT; URLStr = URLStr + "&routeType=" + ROUTETYPE; URLStr = URLStr + "&locale=" + LANGUAGE; URL url = new URL(URLStr); httpConn = (HttpURLConnection) url.openConnection(); httpConn.setRequestMethod("GET"); final int status = httpConn.getResponseCode(); List description = new ArrayList(); List lat = new ArrayList(); List lon = new ArrayList(); List mapUrl= new ArrayList(); String Msg = ""; String distance = ""; if (status == HttpURLConnection.HTTP_OK) { inputStream = httpConn.getInputStream(); BufferedReader in = new BufferedReader(new InputStreamReader(httpConn.getInputStream())); String inputLine; final StringBuffer response = new StringBuffer(); while ((inputLine = in.readLine()) != null) { response.append(inputLine); } final String responseStr = response.toString(); String ImportantValues = ""; if (responseStr.indexOf("maneuvers") != -1) { distance = responseStr.substring(responseStr.indexOf("distance")+10); distance = distance.substring(0, distance.indexOf(",")); ImportantValues = responseStr.substring(responseStr.indexOf("maneuvers")); ImportantValues = ImportantValues.substring(ImportantValues.indexOf("narrative")+12); ImportantValues = ImportantValues.substring(0,ImportantValues.indexOf("options")); String desc = ""; String latStr = ""; String lonStr = ""; String mapUrlStr = ""; while (ImportantValues.indexOf("narrative") != -1) { desc = ImportantValues.substring(0,ImportantValues.indexOf("\"")); description.add(desc); latStr = ImportantValues.substring(ImportantValues.indexOf("lat")+5); latStr = latStr.substring(0,latStr.indexOf("}")); lat.add(latStr); lonStr = ImportantValues.substring(ImportantValues.indexOf("lng")+5); lonStr = lonStr.substring(0,lonStr.indexOf(",")); lon.add(lonStr); mapUrlStr = ImportantValues.substring(ImportantValues.indexOf("mapUrl")+9); mapUrlStr = mapUrlStr.substring(0,mapUrlStr.indexOf("&session")); mapUrl.add(mapUrlStr); ImportantValues = ImportantValues.substring(ImportantValues.indexOf("narrative")+12); } desc = ImportantValues.substring(0,ImportantValues.indexOf("\"")); description.add(desc); latStr = ImportantValues.substring(ImportantValues.indexOf("lat")+5); latStr = latStr.substring(0,latStr.indexOf("}")); lat.add(latStr); lonStr = ImportantValues.substring(ImportantValues.indexOf("lng")+5); lonStr = lonStr.substring(0,lonStr.indexOf(",")); lon.add(lonStr); } else { if (responseStr.indexOf("messages") != -1) { ImportantValues = responseStr.substring(responseStr.indexOf("messages")+12); ImportantValues = ImportantValues.substring(0,ImportantValues.indexOf("\"")); Msg = ImportantValues; } else { Msg = "No results found"; } } httpConn.disconnect(); final List descriptionFin = description; final List latFin = lat; final List lonFin = lon; final List mapUrlFin = mapUrl; final String Message = Msg; final String distanceFin = distance; // Dispatch the event. activity.runOnUiThread(new Runnable() { @Override public void run() { GotRoute(status, responseStr , YailList.makeList(descriptionFin), YailList.makeList(latFin), YailList.makeList(lonFin), YailList.makeList(mapUrlFin), distanceFin, Message); } }); } else { InputStream inputStreamErr = httpConn.getErrorStream(); BufferedReader in = new BufferedReader(new InputStreamReader(httpConn.getErrorStream())); String inputLine; final StringBuffer response = new StringBuffer(); while ((inputLine = in.readLine()) != null) { response.append(inputLine); } final String responseStr = response.toString(); httpConn.disconnect(); // Dispatch the event. activity.runOnUiThread(new Runnable() { @Override public void run() { GotRoute(status, responseStr , null, null, null, null, "", ""); } }); } } catch (Exception e) { e.printStackTrace(); StringWriter errors = new StringWriter(); e.printStackTrace(new PrintWriter(errors)); appendLog(errors.toString()); } } void Geocode_Exec(String APIKEY, String LOCATION) { try { InputStream inputStream = null; String URLStr = "http://www.mapquestapi.com/geocoding/v1/address"; URLStr = URLStr + "?key=" + APIKEY; URLStr = URLStr + "&location=" + LOCATION; URL url = new URL(URLStr); httpConn = (HttpURLConnection) url.openConnection(); httpConn.setRequestMethod("GET"); final int status = httpConn.getResponseCode(); String Msg = ""; List lat = new ArrayList(); List lon = new ArrayList(); List mapUrl= new ArrayList(); if (status == HttpURLConnection.HTTP_OK) { inputStream = httpConn.getInputStream(); BufferedReader in = new BufferedReader(new InputStreamReader(httpConn.getInputStream())); String inputLine; final StringBuffer response = new StringBuffer(); while ((inputLine = in.readLine()) != null) { response.append(inputLine); } final String responseStr = response.toString(); String ImportantValues = ""; if (responseStr.indexOf("displayLatLng") != -1) { String latStr = ""; String lonStr = ""; String mapUrlStr = ""; ImportantValues = responseStr.substring(responseStr.indexOf("displayLatLng")+17); while (ImportantValues.indexOf("displayLatLng") != -1) { latStr = ImportantValues.substring(ImportantValues.indexOf("lat")+5); latStr = latStr.substring(0,latStr.indexOf(",")); lat.add(latStr); lonStr = ImportantValues.substring(ImportantValues.indexOf("lng")+5); lonStr = lonStr.substring(0,lonStr.indexOf("}")); lon.add(lonStr); mapUrlStr = ImportantValues.substring(ImportantValues.indexOf("mapUrl")+9); mapUrlStr = mapUrlStr.substring(0,mapUrlStr.indexOf("}")); mapUrl.add(mapUrlStr); ImportantValues = ImportantValues.substring(ImportantValues.indexOf("displayLatLng")+17); } latStr = ImportantValues.substring(ImportantValues.indexOf("lat")+5); latStr = latStr.substring(0,latStr.indexOf(",")); lat.add(latStr); lonStr = ImportantValues.substring(ImportantValues.indexOf("lng")+5); lonStr = lonStr.substring(0,lonStr.indexOf("}")); lon.add(lonStr); mapUrlStr = ImportantValues.substring(ImportantValues.indexOf("mapUrl")+9); mapUrlStr = mapUrlStr.substring(0,mapUrlStr.indexOf("}")); mapUrl.add(mapUrlStr); } else { if (responseStr.indexOf("messages") != -1) { ImportantValues = responseStr.substring(responseStr.indexOf("messages")+12); ImportantValues = ImportantValues.substring(0,ImportantValues.indexOf("\"")); Msg = ImportantValues; } else { Msg = "No results found"; } } httpConn.disconnect(); final List latFin = lat; final List lonFin = lon; final List mapUrlFin = mapUrl; final String Message = Msg; // Dispatch the event. activity.runOnUiThread(new Runnable() { @Override public void run() { GotGeocode(status, responseStr, YailList.makeList(latFin), YailList.makeList(lonFin), YailList.makeList(mapUrlFin), Message); } }); } else { InputStream inputStreamErr = httpConn.getErrorStream(); BufferedReader in = new BufferedReader(new InputStreamReader(httpConn.getErrorStream())); String inputLine; final StringBuffer response = new StringBuffer(); while ((inputLine = in.readLine()) != null) { response.append(inputLine); } final String responseStr = response.toString(); httpConn.disconnect(); final List descriptionFin = null;final List latFin = null; final List lonFin = null; final List mapUrlFin = null; // Dispatch the event. activity.runOnUiThread(new Runnable() { @Override public void run() { GotGeocode(status, responseStr , null, null, null, null); } }); } } catch (Exception e) { e.printStackTrace(); StringWriter errors = new StringWriter(); e.printStackTrace(new PrintWriter(errors)); appendLog(errors.toString()); } } void ReverseGeocode_Exec(String APIKEY, String LATITUDE, String LONGITUDE) { try { InputStream inputStream = null; String URLStr = "http://www.mapquestapi.com/geocoding/v1/reverse"; URLStr = URLStr + "?key=" + APIKEY; URLStr = URLStr + "&location=" + LATITUDE +"," + LONGITUDE; URLStr = URLStr + "&includeRoadMetadata=true&includeNearestIntersection=true"; URL url = new URL(URLStr); httpConn = (HttpURLConnection) url.openConnection(); httpConn.setRequestMethod("GET"); final int status = httpConn.getResponseCode(); String Address = ""; String MapURL = ""; String Msg = ""; if (status == HttpURLConnection.HTTP_OK) { inputStream = httpConn.getInputStream(); BufferedReader in = new BufferedReader(new InputStreamReader(httpConn.getInputStream())); String inputLine; final StringBuffer response = new StringBuffer(); while ((inputLine = in.readLine()) != null) { response.append(inputLine); } final String responseStr = response.toString(); String ImportantValues = ""; if (responseStr.indexOf("street") != -1) { ImportantValues = responseStr.substring(responseStr.indexOf("street")); Address = ImportantValues.substring(ImportantValues.indexOf("street")+9); Address = Address.substring(0, Address.indexOf("\"")); String adminArea6 = ImportantValues.substring(ImportantValues.indexOf("adminArea6")+13); adminArea6 = adminArea6.substring(0, adminArea6.indexOf("\"")); String adminArea5 = ImportantValues.substring(ImportantValues.indexOf("adminArea5")+13); adminArea5 = adminArea5.substring(0, adminArea5.indexOf("\"")); String adminArea4 = ImportantValues.substring(ImportantValues.indexOf("adminArea4")+13); adminArea4 = adminArea4.substring(0, adminArea4.indexOf("\"")); String adminArea3 = ImportantValues.substring(ImportantValues.indexOf("adminArea3")+13); adminArea3 = adminArea3.substring(0, adminArea3.indexOf("\"")); String adminArea1 = ImportantValues.substring(ImportantValues.indexOf("adminArea1")+13); adminArea1 = adminArea1.substring(0, adminArea1.indexOf("\"")); String postalCode = ImportantValues.substring(ImportantValues.indexOf("postalCode")+13); postalCode = postalCode.substring(0, postalCode.indexOf("\"")); Address = Address + " " + adminArea6 + " " + adminArea5 + " " + adminArea4 + " " + adminArea3 + " " + adminArea1 + " " + postalCode; MapURL = ImportantValues.substring(ImportantValues.indexOf("mapUrl")+9); MapURL = MapURL.substring(0,MapURL.indexOf("\"")); } else { if (responseStr.indexOf("messages") != -1) { ImportantValues = responseStr.substring(responseStr.indexOf("messages")+12); ImportantValues = ImportantValues.substring(0,ImportantValues.indexOf("\"")); Msg = ImportantValues; } else { Msg = "No results found"; } } httpConn.disconnect(); final String AddressFin = Address; final String MapURLFin = MapURL; final String Message = Msg; // Dispatch the event. activity.runOnUiThread(new Runnable() { @Override public void run() { GotReverseGeocode(status, responseStr , AddressFin, MapURLFin, Message); } }); } else { InputStream inputStreamErr = httpConn.getErrorStream(); BufferedReader in = new BufferedReader(new InputStreamReader(httpConn.getErrorStream())); String inputLine; final StringBuffer response = new StringBuffer(); while ((inputLine = in.readLine()) != null) { response.append(inputLine); } final String responseStr = response.toString(); httpConn.disconnect(); // Dispatch the event. activity.runOnUiThread(new Runnable() { @Override public void run() { GotReverseGeocode(status, responseStr , "", "", ""); } }); } } catch (Exception e) { e.printStackTrace(); StringWriter errors = new StringWriter(); e.printStackTrace(new PrintWriter(errors)); appendLog(errors.toString()); } } void PlaceSearch_Exec(String APIKEY, String LATITUDE, String LONGITUDE, String SORT, String RADIUS, String POI) { try { InputStream inputStream = null; String URLStr = "https://www.mapquestapi.com/search/v4/place"; URLStr = URLStr + "?key=" + APIKEY; URLStr = URLStr + "&location=" + LONGITUDE + "," + LATITUDE; URLStr = URLStr + "&sort=" + SORT; URLStr = URLStr + "&circle=" + LONGITUDE + "," + LATITUDE + "," + RADIUS; URLStr = URLStr + "&q=" + POI; URL url = new URL(URLStr); httpConn = (HttpURLConnection) url.openConnection(); httpConn.setRequestMethod("GET"); final int status = httpConn.getResponseCode(); String Msg = ""; List lat = new ArrayList(); List lon = new ArrayList(); List Address= new ArrayList(); if (status == HttpURLConnection.HTTP_OK) { inputStream = httpConn.getInputStream(); BufferedReader in = new BufferedReader(new InputStreamReader(httpConn.getInputStream())); String inputLine; final StringBuffer response = new StringBuffer(); while ((inputLine = in.readLine()) != null) { response.append(inputLine); } final String responseStr = response.toString(); String ImportantValues = ""; if (responseStr.indexOf("displayString") != -1) { String Coordinates = ""; String lonStr = ""; String latStr = ""; String AddressStr = ""; ImportantValues = responseStr.substring(responseStr.indexOf("displayString")+16); while (ImportantValues.indexOf("displayString") != -1) { Coordinates = ImportantValues.substring(ImportantValues.indexOf("coordinates")+14); Coordinates = Coordinates.substring(0,Coordinates.indexOf("]")); lonStr = Coordinates.substring(0,Coordinates.indexOf(",")); lon.add(lonStr); latStr = Coordinates.substring(Coordinates.indexOf(",")+1,Coordinates.length()); lat.add(latStr); //AddressStr = ImportantValues.substring(ImportantValues.indexOf("displayString")+16); //AddressStr = AddressStr.substring(0,AddressStr.indexOf("\"")); //Address.add(AddressStr); AddressStr = ImportantValues.substring(0,ImportantValues.indexOf("\"")); Address.add(AddressStr); ImportantValues = ImportantValues.substring(ImportantValues.indexOf("displayString")+16); } Coordinates = ImportantValues.substring(ImportantValues.indexOf("coordinates")+14); Coordinates = Coordinates.substring(0,Coordinates.indexOf("]")); lonStr = Coordinates.substring(0,Coordinates.indexOf(",")); lon.add(lonStr); latStr = Coordinates.substring(Coordinates.indexOf(",")+1,Coordinates.length()); lat.add(latStr); //AddressStr = ImportantValues.substring(ImportantValues.indexOf("displayString")+16); //AddressStr = AddressStr.substring(0,AddressStr.indexOf("\"")); AddressStr = ImportantValues.substring(0,ImportantValues.indexOf("\"")); Address.add(AddressStr); } else { if (responseStr.indexOf("messages") != -1) { ImportantValues = responseStr.substring(responseStr.indexOf("messages")+12); ImportantValues = ImportantValues.substring(0,ImportantValues.indexOf("\"")); Msg = ImportantValues; } else { Msg = "No results found"; } } httpConn.disconnect(); final List latFin = lat; final List lonFin = lon; final List AddressFin = Address; final String Message = Msg; // Dispatch the event. activity.runOnUiThread(new Runnable() { @Override public void run() { GotPlaceSearch(status, responseStr, YailList.makeList(latFin), YailList.makeList(lonFin), YailList.makeList(AddressFin), Message); } }); } else { InputStream inputStreamErr = httpConn.getErrorStream(); BufferedReader in = new BufferedReader(new InputStreamReader(httpConn.getErrorStream())); String inputLine; final StringBuffer response = new StringBuffer(); while ((inputLine = in.readLine()) != null) { response.append(inputLine); } final String responseStr = response.toString(); httpConn.disconnect(); // Dispatch the event. activity.runOnUiThread(new Runnable() { @Override public void run() { GotPlaceSearch(status, responseStr , null, null, null, null); } }); } } catch (Exception e) { e.printStackTrace(); StringWriter errors = new StringWriter(); e.printStackTrace(new PrintWriter(errors)); appendLog(errors.toString()); } } public void appendLog(String text) { File logFile = new File("sdcard/MapQuestLog.txt"); if (!logFile.exists()) { try { logFile.createNewFile(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } try { //BufferedWriter for performance, true to set append to file flag BufferedWriter buf = new BufferedWriter(new FileWriter(logFile, true)); buf.append(text); buf.newLine(); buf.flush(); buf.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }