package esri.mrm.mobile.activity;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.os.Bundle;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.Toast;
import com.esri.android.map.Layer;
import com.esri.android.map.MapView;
import com.esri.android.map.ags.ArcGISFeatureLayer;
import com.esri.android.map.ags.ArcGISTiledMapServiceLayer;
import com.esri.android.map.event.OnStatusChangedListener;
import com.esri.core.map.CallbackListener;
import com.esri.core.map.FeatureSet;
import com.esri.core.map.Field;
import com.esri.core.map.Graphic;
import com.esri.core.portal.Portal;
import com.esri.core.portal.WebMap;
import com.esri.core.tasks.ags.query.Query;
import esri.mrm.mobile.AGSObjects;
import esri.mrm.mobile.R;
import esri.mrm.mobile.WorkOrderStatus;
public class NavigationActivity extends Activity implements OnSharedPreferenceChangeListener
{
MapView map = null;
ArcGISTiledMapServiceLayer tiledMapService;
private Toast toast;
private long lastBackPressTime = 0;
private AGSObjects agsObjects;
private ProgressDialog progressDialog;
private String webmapItemId;
private String layernameStops;
private String layernameStopsPending;
private String layernameVehicles;
private String layernameRoutes;
private String layernameMessages;
private String layernameMessagesPending;
private String layernameRouteAssignment;
private int refreshInterval;
private SharedPreferences sharedPrefs;
private Portal portal;
/** Called when the activity is first created. */
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);
agsObjects = ((AGSObjects) getApplicationContext());
loadPreferences();
loadMap();
}
private void loadPreferences()
{
webmapItemId = sharedPrefs.getString("webmap_item_id", null);
layernameStops = sharedPrefs.getString("layername_stops", null);
layernameStopsPending = sharedPrefs.getString("layername_stops_pending", null);
layernameVehicles = sharedPrefs.getString("layername_vehicles", null);
layernameRoutes = sharedPrefs.getString("layername_routes", null);
layernameMessages = sharedPrefs.getString("layername_messages", null);
layernameMessagesPending = sharedPrefs.getString("layername_messages_pending", null);
layernameRouteAssignment = sharedPrefs.getString("layername_route_assignment", null);
refreshInterval = Integer.parseInt(sharedPrefs.getString("layer_refresh_interval", "10000"));
agsObjects.setStopsLayer(null);
agsObjects.setRoutesLayer(null);
agsObjects.setStopsPendingLayer(null);
agsObjects.setMessagesLayer(null);
agsObjects.setMessagesPendingLayer(null);
portal = agsObjects.getPortal();
}
private void loadMap()
{
if(webmapItemId == null || webmapItemId.length()==0)
{
return;
}
showProgressDialog();
try
{
WebMap.newInstance(webmapItemId, portal,
new CallbackListener<WebMap>() {
public void onError(Throwable e) {
if (progressDialog != null)
progressDialog.dismiss();
final String error = e.getMessage();
NavigationActivity.this.runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(NavigationActivity.this,
"Webmap failed to load: " + error,
Toast.LENGTH_LONG).show();
}
});
}
public void onCallback(final WebMap webmap) {
// Add the mapview in the ui thread.
NavigationActivity.this.runOnUiThread(new Runnable() {
public void run() {
if (webmap != null){
map = new MapView(NavigationActivity.this, webmap, "", null);
map.setOnStatusChangedListener(new OnStatusChangedListener() {
private static final long serialVersionUID = 1L;
public void onStatusChanged(Object source, STATUS status) {
if(status.getValue() == EsriStatusException.INIT_FAILED_WEBMAP_UNSUPPORTED_LAYER)
{
Toast.makeText(NavigationActivity.this,
"Webmap failed to load",
Toast.LENGTH_LONG).show();
}
else if (source == map && status == STATUS.INITIALIZED)
{
Layer[] layers = map.getLayers();
for (Layer layer : layers)
{
// layer.setVisible(false);
if (layer.isInitialized())
{
if (layer instanceof ArcGISFeatureLayer)
{
ArcGISFeatureLayer agsLayer = (ArcGISFeatureLayer) layer;
drawLayers(agsLayer);
}
}
else
{
layer.setOnStatusChangedListener(new OnStatusChangedListener()
{
/**
*
*/
private static final long serialVersionUID = 1L;
public void onStatusChanged(Object arg0, STATUS arg1)
{
if (arg0 instanceof ArcGISFeatureLayer && arg1 == STATUS.INITIALIZED)
{
ArcGISFeatureLayer agsLayer = (ArcGISFeatureLayer) arg0;
drawLayers(agsLayer);
}
}
});
}
}
}
else if (source == map && status == STATUS.INITIALIZATION_FAILED)
{
if (progressDialog != null)
progressDialog.dismiss();
}
}
});
setContentView(map);
}
}
});
}
});
}
catch(Exception e)
{
Toast.makeText(NavigationActivity.this,
"Webmap failed to load: " + e.getMessage(),
Toast.LENGTH_LONG).show();
}
}
private void drawLayers(ArcGISFeatureLayer agsLayer)
{
if (agsLayer.getName().equals(layernameStops))
drawStopLayer(agsLayer);
else if (agsLayer.getName().equals(layernameVehicles))
drawVehicleLayer(agsLayer);
else if (agsLayer.getName().equals(layernameRoutes))
drawRouteLayer(agsLayer);
else if (agsLayer.getName().equals(layernameRouteAssignment))
queryRouteAssignmentLayer(agsLayer);
else if (agsLayer.getName().equals(layernameMessages))
drawMessageLayer(agsLayer);
else if (agsLayer.getName().equals(layernameMessagesPending))
{
agsLayer.setVisible(false);
agsObjects.setMessagesPendingLayer(agsLayer);
}
else if (agsLayer.getName().equals(layernameStopsPending))
{
agsLayer.setVisible(false);
agsObjects.setStopsPendingLayer(agsLayer);
}
else
{
agsLayer.setVisible(false);
}
}
private void queryRouteLayer(ArcGISFeatureLayer layer)
{
System.out.println(" --- " + "Called queryRouteLayer." + " --- ");
//String queryString = getResources().getString(R.string.KEY_ROUTE_NAME) + "='" + agsObjects.getRouteId() + "'";
String routeFieldName = getFieldNamebyAlias(layer, getResources().getString(R.string.ALIAS_ROUTESLAYER_ROUTE));
final String vehicleFieldName = getFieldNamebyAlias(layer, getResources().getString(R.string.ALIAS_ROUTESLAYER_Vehicle));
String queryString = routeFieldName + "='" + agsObjects.getRouteId() + "'";
System.out.println(" --- " + "query string is " + queryString + " --- ");
Query query = new Query();
query.setWhere(queryString);
query.setOutFields(new String[] { "*" });
layer.queryFeatures(query, new CallbackListener<FeatureSet>()
{
public void onError(Throwable arg0)
{
System.out.println(" --- " + "queryRouteLayer error." + " --- ");
progressDialog.dismiss();
}
public void onCallback(FeatureSet queryResults)
{
if (queryResults.getGraphics().length > 0)
{
Graphic graphic = queryResults.getGraphics()[0];
if(graphic.getGeometry() != null)
map.setExtent(graphic.getGeometry(), 60);
String vehicleId = (String) graphic.getAttributeValue(vehicleFieldName);
System.out.println(" --- " + "Got Veh ID " + vehicleId + " --- ");
agsObjects.setVehicleId(vehicleId);
if (agsObjects.getVehiclesLayer() != null)
{
drawVehicleLayer(agsObjects.getVehiclesLayer());
}
}
else
{
System.out.println(" --- " + "queryRouteLayer got nothing." + " --- ");
}
progressDialog.dismiss();
}
});
}
private void queryRouteAssignmentLayer(ArcGISFeatureLayer layer)
{
System.out.println(" --- " + "Called queryRouteAssignmentLayer." + " --- ");
final String accountName = agsObjects.getUsername();
String accountNameFieldName = getFieldNamebyAlias(layer, getResources().getString(R.string.KEY_ACCOUNT_NAME_RA));
final String routeNameFieldName = getFieldNamebyAlias(layer, getResources().getString(R.string.KEY_ROUTE_NAME_RA));
String queryString = accountNameFieldName + "='" + accountName + "'";
System.out.println(" --- " + "query string is " + queryString + " --- ");
Query query = new Query();
query.setWhere(queryString);
query.setOutFields(new String[] { "*" });
layer.queryFeatures(query, new CallbackListener<FeatureSet>()
{
public void onError(Throwable arg0)
{
System.out.println(" --- " + "queryRouteAssignmentLayer error." + " --- ");
progressDialog.dismiss();
}
public void onCallback(FeatureSet queryResults)
{
if (queryResults.getGraphics().length > 0)
{
Graphic graphic = queryResults.getGraphics()[0];
String routeId = (String) graphic.getAttributeValue(routeNameFieldName);
System.out.println(" --- " + "Got Route ID " + routeId + " --- ");
agsObjects.setRouteId(routeId);
if (agsObjects.getRoutesLayer() != null)
drawRouteLayer(agsObjects.getRoutesLayer());
if (agsObjects.getStopsLayer() != null)
drawStopLayer(agsObjects.getStopsLayer());
if(agsObjects.getMessagesLayer() != null)
drawMessageLayer(agsObjects.getMessagesLayer());
}
else
{
System.out.println(" --- " + "queryRouteAssignmentLayer got nothing." + " --- ");
progressDialog.dismiss();
showAlertMessage("Warning", "No route is assigned to " + accountName);
}
}
});
}
private void drawStopLayer(ArcGISFeatureLayer agsLayer)
{
System.out.println(" --- " + "Called drawStopLayer." + " --- ");
if (agsObjects.getRouteId() != null)
{
String routeFieldName = getFieldNamebyAlias(agsLayer, getResources().getString(R.string.ALIAS_STOPSLAYER_ROUTE_NAME));
String statusFieldName = getFieldNamebyAlias(agsLayer, getResources().getString(R.string.ALIAS_STOPSLAYER_STATUS));
final String whereClause = routeFieldName + "='" + agsObjects.getRouteId() + "' and "
+ statusFieldName + " in ('" + WorkOrderStatus.Dispatched.toString() + "','" + WorkOrderStatus.AtStop.toString() + "','"
+ WorkOrderStatus.Completed.toString() + "','" + WorkOrderStatus.Exception.toString() + "')";
System.out.println(" --- " + "Where clause is " + whereClause + " --- ");
agsLayer.setDefinitionExpression(whereClause);
agsLayer.setVisible(true);
agsLayer.refresh();
}
else
{
System.out.println(" --- " + "Route ID is null." + " --- ");
agsLayer.setVisible(false);
}
agsLayer.setAutoRefreshOnExpiration(true);
agsLayer.setExpirationInterval(refreshInterval/1000);
agsObjects.setStopsLayer(agsLayer);
}
private void drawMessageLayer(ArcGISFeatureLayer agsLayer)
{
System.out.println(" --- " + "Called drawMsgLayer." + " --- ");
if (agsObjects.getRouteId() != null)
{
String msgTo = getFieldNamebyAlias(agsLayer, getResources().getString(R.string.ALIAS_MESSAGESLAYER_MESSAGE_TO));
final String whereClause = msgTo + "='" + agsObjects.getRouteId() + "'";
System.out.println(" --- " + "Where clause is " + whereClause + " --- ");
agsLayer.setDefinitionExpression(whereClause);
agsLayer.refresh();
}
else
System.out.println(" --- " + "Route ID is null." + " --- ");
agsLayer.setVisible(false);
agsLayer.setAutoRefreshOnExpiration(true);
agsLayer.setExpirationInterval(refreshInterval/1000);
agsObjects.setMessagesLayer(agsLayer);
}
private void drawVehicleLayer(ArcGISFeatureLayer agsLayer)
{
System.out.println(" --- " + "Called drawVehLayer." + " --- ");
if (agsObjects.getVehicleId() != null)
{
String vehicleFieldName = getFieldNamebyAlias(agsLayer, getResources().getString(R.string.ALIAS_VEHICLESSLAYER_Vehicle));
final String whereClause = vehicleFieldName + "='" + agsObjects.getVehicleId() + "'";
System.out.println(" --- " + "Where clause is " + whereClause + " --- ");
agsLayer.setDefinitionExpression(whereClause);
agsLayer.setVisible(true);
agsLayer.refresh();
}
else
{
agsLayer.setVisible(false);
System.out.println(" --- " + "Veh ID is null." + " --- ");
}
agsLayer.setAutoRefreshOnExpiration(true);
agsLayer.setExpirationInterval(refreshInterval/1000);
agsObjects.setVehiclesLayer(agsLayer);
}
private void drawRouteLayer(ArcGISFeatureLayer agsLayer)
{
System.out.println(" --- " + "Called drawRouteLayer." + " --- ");
if (agsObjects.getRouteId() != null)
{
queryRouteLayer(agsLayer);
String routeFieldName = getFieldNamebyAlias(agsLayer, getResources().getString(R.string.ALIAS_ROUTESLAYER_ROUTE));
String statusFieldName = getFieldNamebyAlias(agsLayer, getResources().getString(R.string.ALIAS_ROUTESLAYER_Status));
final String whereClause = routeFieldName + "='" + agsObjects.getRouteId() + "' and " + statusFieldName + "='Dispatched'";
System.out.println(" --- " + "Where clause is " + whereClause + " --- ");
agsLayer.setDefinitionExpression(whereClause);
agsLayer.setVisible(true);
agsLayer.refresh();
}
else
{
agsLayer.setVisible(false);
System.out.println(" --- " + "Route ID is null." + " --- ");
}
agsLayer.setAutoRefreshOnExpiration(true);
agsLayer.setExpirationInterval(refreshInterval/1000);
agsObjects.setRoutesLayer(agsLayer);
}
private String getFieldNamebyAlias(ArcGISFeatureLayer layer, String alias)
{
String out = "";
Field[] fields = layer.getFields();
for(int i=0; i<fields.length; i++)
{
if(fields[i].getAlias().equals(alias))
out = fields[i].getName();
}
return out;
}
private void showProgressDialog()
{
progressDialog = new ProgressDialog(this);
progressDialog.setTitle("Initializing Map");
progressDialog.setMessage("Please wait...");
progressDialog.setCancelable(false);
progressDialog.setIndeterminate(true);
progressDialog.show();
timerDelayRemoveDialog(30000, progressDialog);
}
@Override
public void onBackPressed()
{
if (this.lastBackPressTime < System.currentTimeMillis() - 4000)
{
toast = Toast.makeText(this, "Press Back button agian to close the app", Toast.LENGTH_LONG);
toast.show();
this.lastBackPressTime = System.currentTimeMillis();
}
else
{
if (toast != null)
{
toast.cancel();
}
super.onBackPressed();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.mrm_menu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
// Handle item selection
switch (item.getItemId())
{
case R.id.settings:
Intent intent = new Intent(this, FieldWorkerAppPreference.class);
intent.putExtra("settingsId", R.xml.preference);
startActivity(intent);
return true;
default:
return true;
}
}
private void cleanup()
{
if (map != null)
{
Layer[] layers = map.getLayers();
for (Layer layer : layers)
{
if (layer instanceof ArcGISFeatureLayer)
{
((ArcGISFeatureLayer) layer).setAutoRefreshOnExpiration(false);
}
}
}
if(agsObjects != null)
agsObjects.clear();
map = null;
}
protected void onPause()
{
super.onPause();
if(map != null)
map.pause();
// sharedPrefs.unregisterOnSharedPreferenceChangeListener(this);
}
protected void onResume()
{
super.onResume();
if(map != null)
map.unpause();
// sharedPrefs.registerOnSharedPreferenceChangeListener(this);
}
@Override
protected void onDestroy()
{
super.onDestroy();
cleanup();
}
@Override
protected void onStop()
{
super.onStop();
}
public void onSharedPreferenceChanged(SharedPreferences arg0, String arg1)
{
loadPreferences();
loadMap();
}
public void timerDelayRemoveDialog(long time, final Dialog d){
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
if(d != null)
d.dismiss();
}
}, time);
}
private void showAlertMessage(final String title, final String body)
{
NavigationActivity.this.runOnUiThread(new Runnable()
{
public void run()
{
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(NavigationActivity.this);
// set title
alertDialogBuilder.setTitle(title);
// set dialog message
alertDialogBuilder.setMessage(body).setCancelable(false).setPositiveButton(R.string.okButtonLabel, new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int id)
{
dialog.cancel();
}
});
// create alert dialog
AlertDialog alertDialog = alertDialogBuilder.create();
// show it
alertDialog.show();
}
});
}
}