This document summarizes a presentation on developing Android applications with ArcGIS Server. It discusses what Android is, pros and cons of choosing Android over iPhone, how to get started with Android development, design considerations for mobile apps, and how to integrate ArcGIS Server data and services using REST APIs and the Google Maps API. Code examples are provided for creating map overlays with WMS tiles and collecting and posting field data to a feature service.
Take control of your SAP testing with UiPath Test Suite
Develop Android Apps with ArcGIS Server Data and Services
1. Android Development with ArcGIS Server Esri Dev Meet Up Charlotte, NC October 19th, 2010 Jim Tochterman, VP - Research & Development www.bcs-gis.com www.facebook.com/bcsgis www.twitter.com/bcsgis
2. What is Android? Software stack for mobile devices, formally introduced in 2008 Unlike other mobile devices, not a proprietary OS iOS Palm OS Blackberry OS Combination of three (3) components Free, open source OS for mobile devices Free, open source development environment for creating mobile applications Devices that run the Android OS and the applications created for it http://developer.android.com/guide/basics/what-is-android.html
3. Why choose Android over iPhone? Customers: iPhone cost was prohibitive for widespread deployment No Objective-C / Cocoa developers on staff No Mac hardware available Technical Limitations / General Annoyances: GSM coverage is not good in the Southeast (even in Urban Areas) iPhone did not support “backgrounding” (at the time) Deployment Hurdles (App Store, Code Signing, etc.) Xcode is quite possibly the worst IDE ever! Comfort Level: If you do Flex or Java development already the tools are very similar!
4. Why develop with Android? Background Services Event driven model that works silently while other applications are being used. Shared Data & Inter-Process Communication Applications can exchanges messages, perform processing, and share data. Widgets & Live Folders Allows you to create windows into your applications from your device’s home screen. Application Equality No differentiation between native applications and those developed by third parties.
5. Pros & Cons with Android Development Pros: Good Development Tools and Samples No App Store / Market Requirement! Build and Deploy with Dropbox if you feel like it Cons: Terminology! What in the hell is an Activity and a Intent!? (The names can seem strange, but based upon what they do) More work to make a “Pretty” app
6. Where Do I Get Started? Download Eclipse (or my preference MotoDev Studio) http://www.eclipse.org/downloads http://developer.motorola.com/docstools/motodevstudio/download Download Android ADT and SDK http://developer.android.com/sdk/index.html Start Playing!
7. Design Considerations For Mobile Devices Low Processing Speed Optimize code to run quick and efficiently Limited storage & memory Minimize application size Reuse and share data (using databases & saved files) Limited bandwidth & high latency Allow for slow, intermittent network connections Limited Battery Life Avoid expensive operations where/when possible Limit sensor access when not being used
8. How do I use ArcGIS Server with Android? ArcGIS API for Android is coming! Finally!! http://resources.arcgis.com/content/arcgis-android/api
9. How do I use ArcGIS Server with Android now!? Sign up for the Early Adopter Program – OR - arcgis4android@esri.com Use ArcGIS Server REST API & Web Services! WMS Service provides Map Tiles for Overlays Feature Service provides ability to retrieve and/or edit data
11. Creating Map Overlay (MainActivity.java) public class MainActivity extends MapActivity implements OnSharedPreferenceChangeListener { private final static String TAG = "MainActivity"; MyMapViewmyMapView; MapControllermapController; LocationManagerlocationManager; MyCustomLocationOverlaymyLocationOverlay; WMSOverlayAtlanticStormsOverlay; … AtlanticStormsOverlay = new WMSOverlay("http://aws.bcs-gis.com/arcgis/services/Storms/Atlantic/MapServer/WMSServer?", layerIds, myMapView); overlays.add(AtlanticStormsOverlay ); … }
12. Creating Map Overlay (WMSOverlay.java) public class WMSOverlay extends Overlay { private final static String TAG = ”WMSOverlay"; WMSLoaderwmsClient; … public WMSOverlay(Stringurl, String layers, MapViewmapView) { … wmsClient = new WMSLoader(url, layers); intleftLongitude = mapView.getMapCenter().getLongitudeE6() - mapView.getLongitudeSpan()/2; intrightLongitude = mapView.getMapCenter().getLongitudeE6()+ mapView.getLongitudeSpan()/2; intupperLatitude = mapView.getMapCenter().getLatitudeE6() + mapView.getLatitudeSpan()/2; intlowerLatitude = mapView.getMapCenter().getLatitudeE6() - mapView.getLatitudeSpan()/2; GeoPointupperLeft = new GeoPoint(upperLatitude,leftLongitude); GeoPointlowerRight = new GeoPoint(lowerLatitude,rightLongitude); image = wmsClient.loadMap(mapView.getWidth(), mapView.getHeight(), upperLeft, lowerRight); } }
13. Creating Map Overlay (WMSLoader.java) public class WMSLoader { public static String TAG = "WMSLoader"; public String serverUrl; public String layerIds; … public Bitmap loadMap(int width, int height, GeoPointul, GeoPointlr) { URL url = null; try { url = new URL(String.format(serverUrl + "LAYERS=" + layerIds + "&TRANSPARENT=true&FORMAT=image/ png&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&STYLES=&EXCEPTIONS=application/ vnd.ogc.se_inimage&SRS=EPSG:4326" + "" + "&BBOX=%f,%f,%f,%f&WIDTH=%d&HEIGHT=%d", ul.getLongitudeE6()/1E6, lr.getLatitudeE6()/1E6, lr.getLongitudeE6 ()/1E6, ul.getLatitudeE6()/1E6, width, height)); … Bitmap image = BitmapFactory.decodeStream(input); return image; } }
14. Creating Data via REST API (MainActivity.java) public class MainActivity extends MapActivity implements OnSharedPreferenceChangeListener { … @Override public booleanonCreateOptionsMenu(Menu menu) { boolean result = super.onCreateOptionsMenu(menu); … menu.add(0, 996, Menu.NONE, "SITREP Notes").setIcon(android.R.drawable.ic_menu_myplaces); … } @Override public booleanonOptionsItemSelected(MenuItem item) { super.onOptionsItemSelected(item); Intent mapIntent = new Intent(Intent.ACTION_VIEW); switch (item.getItemId()) { … case (996) : Intent dca = new Intent(this, DataCollectionActivity.class); startActivityForResult(dca, 996); return true; … } // Return false if you have not handled the menu item. return false; } }
15. Creating Data via REST API (DataCollectionActivity.java) public class DataCollectionActivity extends Activity { static final String TAG = "DataCollectionActivity"; … pointButton.setOnClickListener(newOnClickListener() { public void onClick(Viewv) { //Ask the user if they want to post report new AlertDialog.Builder(DataCollectionActivity.this) .setIcon(android.R.drawable.ic_dialog_alert) .setTitle("Post Note") .setMessage("Are you sure you want to post this note?") .setPositiveButton("Yes", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { Bundle bundle = new Bundle(); bundle.putString("type", pointSpinner.getSelectedItem().toString()); bundle.putString("reportdatetime", deviceData.getReportDateTime()); bundle.putString("comments", commentsEditText.getText().toString()); Intent intent = new Intent(Intent.ACTION_VIEW); intent.putExtras(bundle); intent.setClassName("com.bcs.android.sitrep", "com.bcs.android.sitrep.NoteCreateActivity"); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent); } }) .setNegativeButton("No", null) .show(); … }
16. Creating Data via REST API (NoteCreateActivity.java) public class NoteCreateActivity extends Activity { static final String TAG = "NoteCreateActivity"; private String serverUrl = "http://devweb.bcs-gis.com/arcgis/rest/services/SITREP_Notes2/FeatureServer/0/addFeatures"; … String attrString = ",'attributes':{"; attrString = attrString + "'TYPE':'" + type + "'," + "'RPTDATETIME':'" + reportdatetime + "', " + "'SUMMARY':'" + comments + "'"; attrString = attrString + "}"; String coordString = "[{'geometry':{"; coordString = coordString + "'x':" + loc.getLongitude() + ",'y':" + loc.getLatitude(); coordString = coordString + "}" + attrString + "}]"; HttpClienthttpclient = new DefaultHttpClient(); HttpPosthttppost = new HttpPost(serverUrl); try { // Add your data List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1); nameValuePairs.add(newBasicNameValuePair("features", coordString)); httppost.setEntity(newUrlEncodedFormEntity(nameValuePairs)); // Execute HTTP Post Request httpResponse = httpclient.execute(httppost); … }