diff --git a/libSafeMobile/src/main/java/com/safemobile/activities/AbstractLiveActivity.java b/libSafeMobile/src/main/java/com/safemobile/activities/AbstractLiveActivity.java
index 11a7695..236b078 100644
--- a/libSafeMobile/src/main/java/com/safemobile/activities/AbstractLiveActivity.java
+++ b/libSafeMobile/src/main/java/com/safemobile/activities/AbstractLiveActivity.java
@@ -2,6 +2,7 @@ package com.safemobile.activities;
import java.util.ArrayList;
+import com.google.android.gms.maps.GoogleMap;
import com.safemobile.lib.Vehicle;
import android.app.Activity;
@@ -23,7 +24,7 @@ public abstract class AbstractLiveActivity extends AppCompatActivity {
public abstract void pollReceived(int position, double lat, double lng); // --> UpdatePoll
public abstract void vehicleStatusReceived(long imei, int opCode, int status); // --> UpdateOptions
public abstract void emergencyAlarmReceived(int position, double lat, double lng); // --> UpdateEmergencyAlarm
-
+ public abstract GoogleMap getMap(); // --> UpdateEmergencyAlarm
/** Misc */
public AbstractSDParentActivity getParentTab() {
diff --git a/libSafeMobile/src/main/java/com/safemobile/lib/SuperVehicle.java b/libSafeMobile/src/main/java/com/safemobile/lib/SuperVehicle.java
index 2c9dfb1..2388814 100644
--- a/libSafeMobile/src/main/java/com/safemobile/lib/SuperVehicle.java
+++ b/libSafeMobile/src/main/java/com/safemobile/lib/SuperVehicle.java
@@ -21,36 +21,28 @@ public class SuperVehicle extends Vehicle{
// TODO Auto-generated constructor stub
}
- public void SetDataFromLastPos(Double _lat,Double _lng,long _time,int _speed,String _Address,Boolean _isON)
- {
- try
- {
+ public void SetDataFromLastPos(Double _lat,Double _lng,long _time,int _speed,String _Address,Boolean _isON) {
+ try {
lat = _lat;
lng = _lng;
timeGMT = _time;
speed = _speed;
Address = _Address;
isON = _isON;
- }
- catch (Exception ex)
- {
- Log.d("Erorr", "Contert Error:"+ex.toString());
+ } catch (Exception ex) {
+ Log.d("Erorr", "Contert Error: "+ ex);
}
}
- public void SetNewPosition(Double _lat,Double _lng,long _time,int _speed)
- {
- try
- {
+ public void SetNewPosition(Double _lat,Double _lng,long _time,int _speed) {
+ try {
lat = _lat;
lng = _lng;
timeGMT = _time;
speed = _speed;
isON = true;
- }
- catch (Exception ex)
- {
- Log.d("Erorr", "Contert Error:"+ex.toString());
+ } catch (Exception ex) {
+ Log.d("Erorr", "Contert Error: " + ex);
}
}
diff --git a/libSafeMobile/src/main/res/drawable-xhdpi/custom_info_bubble.9.png b/libSafeMobile/src/main/res/drawable-xhdpi/custom_info_bubble.9.png
new file mode 100644
index 0000000..21dc176
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-xhdpi/custom_info_bubble.9.png differ
diff --git a/libSafeMobile/src/main/res/drawable-xhdpi/l_bg_gps.jpg b/libSafeMobile/src/main/res/drawable-xhdpi/l_bg_gps.jpg
new file mode 100644
index 0000000..e940b10
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-xhdpi/l_bg_gps.jpg differ
diff --git a/libSafeMobile/src/main/res/drawable-xhdpi/l_speed.png b/libSafeMobile/src/main/res/drawable-xhdpi/l_speed.png
new file mode 100644
index 0000000..9451fc2
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-xhdpi/l_speed.png differ
diff --git a/libSafeMobile/src/main/res/drawable-xhdpi/l_street.png b/libSafeMobile/src/main/res/drawable-xhdpi/l_street.png
new file mode 100644
index 0000000..af3f177
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-xhdpi/l_street.png differ
diff --git a/libSafeMobile/src/main/res/drawable-xhdpi/l_time.png b/libSafeMobile/src/main/res/drawable-xhdpi/l_time.png
new file mode 100644
index 0000000..72e4ebf
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-xhdpi/l_time.png differ
diff --git a/libSafeMobile/src/main/res/layout/map_marker_info_bubble.xml b/libSafeMobile/src/main/res/layout/map_marker_info_bubble.xml
new file mode 100644
index 0000000..08ce499
--- /dev/null
+++ b/libSafeMobile/src/main/res/layout/map_marker_info_bubble.xml
@@ -0,0 +1,140 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/libSafeMobile/src/main/res/values/color.xml b/libSafeMobile/src/main/res/values/color.xml
new file mode 100644
index 0000000..503e1f0
--- /dev/null
+++ b/libSafeMobile/src/main/res/values/color.xml
@@ -0,0 +1,5 @@
+
+
+ #FFFFFF
+ #000000
+
\ No newline at end of file
diff --git a/safeDispatch/src/main/java/com/safemobile/dispatch/GoogleMapsInfoBubble.java b/safeDispatch/src/main/java/com/safemobile/dispatch/GoogleMapsInfoBubble.java
new file mode 100644
index 0000000..4aea17d
--- /dev/null
+++ b/safeDispatch/src/main/java/com/safemobile/dispatch/GoogleMapsInfoBubble.java
@@ -0,0 +1,93 @@
+package com.safemobile.dispatch;
+
+import android.content.Context;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+
+import com.google.android.gms.maps.GoogleMap;
+import com.google.android.gms.maps.model.Marker;
+import com.safemobile.lib.SuperVehicle;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Hashtable;
+import java.util.Locale;
+
+
+public class GoogleMapsInfoBubble implements GoogleMap.InfoWindowAdapter {
+ private final String TAG = GoogleMapsInfoBubble.class.getName();
+
+ private final View mWindow;
+ private final Hashtable superVehHash;
+ private final Context context;
+
+
+ public GoogleMapsInfoBubble(LayoutInflater layoutInflater, Context context, Hashtable vehicles) {
+ this.context = context;
+ this.superVehHash = vehicles;
+ mWindow = layoutInflater.inflate(R.layout.map_marker_info_bubble, null);
+ }
+
+ @Override
+ public View getInfoWindow(@NonNull Marker marker) {
+ render(marker, mWindow);
+ return mWindow;
+ }
+
+ @Override
+ public View getInfoContents(@NonNull Marker marker) {
+ render(marker, mWindow);
+ return mWindow;
+ }
+
+ private void render(Marker marker, View view) {
+ long key = 0;
+
+ try {
+ key = Long.parseLong(marker.getTitle());
+ } catch (Exception ex) {
+ Log.v(TAG, "Unable to parse Google Maps Info Bubble title");
+ }
+ SuperVehicle vehicle = superVehHash.get(key);
+
+ RelativeLayout rlMapInfoBubbleInfo = view.findViewById(R.id.rlMapInfoBubbleInfo);
+ TextView tvUnitName = view.findViewById(R.id.tvUnitName);
+ TextView tvGPSLocation = view.findViewById(R.id.tvGPSLocation);
+ TextView tvTimeAgo = view.findViewById(R.id.tvTimeAgo);
+ TextView tvSpeed = view.findViewById(R.id.tvSpeed);
+ TextView tvStreetView = view.findViewById(R.id.tvStreetView);
+ ImageView streetView = view.findViewById(R.id.streetView);
+ rlMapInfoBubbleInfo.setVisibility(View.VISIBLE);
+
+ boolean isMilitaryTime = false;
+ Date positionTime = new Date(vehicle.timeGMT);
+
+
+ String timeFormat = isMilitaryTime
+ ? "HH:mm:ss dd.MMM.yyyy"
+ : "hh:mm:ss a dd.MMM.yyy";
+
+ DateFormat format = new SimpleDateFormat(timeFormat, Locale.ENGLISH);
+
+ tvTimeAgo.setText(format.format(positionTime));
+
+ tvSpeed.setText(String.format(context.getResources().getString(R.string.speedMph), vehicle.speed));
+
+ String address = vehicle.Address != null ? vehicle.Address : "";
+
+ tvStreetView.setText(address);
+ streetView.setVisibility(address.length() > 0 ? View.VISIBLE : View.GONE);
+ tvStreetView.setVisibility(address.length() > 0 ? View.VISIBLE : View.GONE);
+ tvUnitName.setText(vehicle.name);
+ tvGPSLocation.setText("[" + String.format("%.4f", vehicle.lat)
+ + "," + String.format("%.4f",vehicle.lng) + "]");
+ }
+}
+
diff --git a/safeDispatch/src/main/java/com/safemobile/dispatch/HistoryActivity.java b/safeDispatch/src/main/java/com/safemobile/dispatch/HistoryActivity.java
index 87de241..eaa171c 100644
--- a/safeDispatch/src/main/java/com/safemobile/dispatch/HistoryActivity.java
+++ b/safeDispatch/src/main/java/com/safemobile/dispatch/HistoryActivity.java
@@ -3,18 +3,145 @@ package com.safemobile.dispatch;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
+import android.widget.ArrayAdapter;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.Spinner;
+import android.widget.TextView;
+import com.google.android.gms.maps.GoogleMap;
+import com.google.android.gms.maps.SupportMapFragment;
+import com.safemobile.lib.AppParams;
import com.safemobile.lib.SM;
+import com.safemobile.lib.Vehicle;
+
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Locale;
public class HistoryActivity extends AppCompatActivity {
public Bundle savedInstanceState;
+ private TabLayoutActivity parentTab;
+ private GoogleMap googleMap;
+ private Spinner spinnerVehicle;
+ private ImageView changeMapType, checkTraffic, slideLayoutImage;
+ private LinearLayout layoutTraffic, slidelayout, layoutVehicles;
+
+ private ArrayList allVehicle = new ArrayList<>();
+ private ArrayList allVehicleNames = new ArrayList<>();
+ private ArrayAdapter adapter;
+ private boolean showVehicle = true;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.savedInstanceState = savedInstanceState;
setContentView(R.layout.tabhistory);
+
+ parentTab = (TabLayoutActivity) getParent();
+ parentTab.historyActivity = this;
+
+ Locale locale = new Locale(AppParams.LANGUAGETMP);
+ Locale.setDefault(locale);
+
+ googleMap = parentTab.liveActivity.getMap();
+ SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
+ .findFragmentById(R.id.map);
+
+ spinnerVehicle = findViewById(R.id.spinnerVehicle);
+ getVehicles();
+
+ adapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, allVehicleNames);
+ adapter.setDropDownViewResource(android.R.layout.simple_dropdown_item_1line);
+ spinnerVehicle.setAdapter(adapter);
+ spinnerVehicle.setSelection(0);
+
+ changeMapType();
+ changeTraffic();
+
+ slidelayout = findViewById(R.id.slidelayout);
+ slideLayoutImage = findViewById(R.id.slideLayoutImage);
+ layoutVehicles = findViewById(R.id.layoutBig);
+// slidelayout.setOnTouchListener((v, event) -> {
+// if (showVehicle) {
+// layoutVehicles.setVisibility(View.GONE);
+// slideLayoutImage.setImageResource(R.drawable.arrow_right);
+// showVehicle = false;
+// } else {
+// layoutVehicles.setVisibility(View.VISIBLE);
+// slideLayoutImage.setImageResource(R.drawable.arrow_left);
+// showVehicle = true;
+// }
+// return false;
+// });
+
+ setDate();
+ }
+
+ private void setDate() {
+ Calendar calendar = Calendar.getInstance();
+ Date endDate = calendar.getTime();
+ calendar.add(Calendar.DATE, -1);
+ Date startDate = calendar.getTime();
+
+ LinearLayout layoutStartPicker = findViewById(R.id.layoutStartPicker);
+ TextView textViewDate = findViewById(R.id.textViewStartDate);
+
+ textViewDate.setText(new SimpleDateFormat("HH:mm, dd.MM.yyyy").format(startDate));
+// layoutStartPicker.setOnTouchListener((v, event) -> {
+// showDialog(layoutStartPicker);
+// return false;
+// });
+
+// layoutEndPicker.setOnTouchListener(new OnTouchListener() {
+// @Override
+// public boolean onTouch(View v, MotionEvent event) {
+// showDialog(layoutEndPicker);
+// return false;
+// }
+// });
+
+
+ }
+
+ private void changeTraffic() {
+ ImageView changeTrafficImageView = findViewById(R.id.changeTraffic);
+ changeTrafficImageView.setOnClickListener(v -> {
+ if (googleMap.isTrafficEnabled()) {
+ changeTrafficImageView.setImageResource(R.drawable.traffic_off);
+ googleMap.setTrafficEnabled(false);
+ } else {
+ changeTrafficImageView.setImageResource(R.drawable.traffic);
+ googleMap.setTrafficEnabled(true);
+ }
+ });
+ }
+
+ private void changeMapType() {
+ changeMapType = findViewById(R.id.changeMapType);
+ ImageView changeMapTypeImageView = findViewById(R.id.changeMapType);
+ changeMapType.setOnClickListener(view -> {
+ if (googleMap.getMapType() == GoogleMap.MAP_TYPE_SATELLITE) {
+ changeMapTypeImageView.setImageResource(R.drawable.satellite);
+ googleMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
+ } else {
+ changeMapTypeImageView.setImageResource(R.drawable.map);
+ googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
+ }
+ });
+ }
+
+ public void getVehicles() {
+ try {
+ for (Vehicle vehicle : parentTab.getAllVehicle()) {
+ allVehicleNames.add(vehicle.name);
+ allVehicle.add(vehicle);
+ }
+ } catch (Exception ex) { }
+
}
public void UpdateMap() {
diff --git a/safeDispatch/src/main/java/com/safemobile/dispatch/IconContextMenu.java b/safeDispatch/src/main/java/com/safemobile/dispatch/IconContextMenu.java
index 22fb898..bcd2fae 100644
--- a/safeDispatch/src/main/java/com/safemobile/dispatch/IconContextMenu.java
+++ b/safeDispatch/src/main/java/com/safemobile/dispatch/IconContextMenu.java
@@ -42,10 +42,9 @@ public class IconContextMenu implements DialogInterface.OnCancelListener,
private static final int LIST_PREFERED_HEIGHT = 65;
- private IconMenuAdapter menuAdapter = null;
- private Activity parentActivity = null;
- private int dialogId = 0;
-
+ private IconMenuAdapter menuAdapter;
+ private Activity parentActivity;
+
private IconContextMenuOnClickListener clickHandler = null;
/**
@@ -55,8 +54,7 @@ public class IconContextMenu implements DialogInterface.OnCancelListener,
*/
public IconContextMenu(Activity parent, int id) {
this.parentActivity = parent;
- this.dialogId = id;
-
+
menuAdapter = new IconMenuAdapter(parentActivity);
}
@@ -89,19 +87,13 @@ public class IconContextMenu implements DialogInterface.OnCancelListener,
public Dialog createMenu(String menuItitle) {
final AlertDialog.Builder builder = new AlertDialog.Builder(parentActivity);
builder.setTitle(menuItitle);
- builder.setAdapter(menuAdapter, new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialoginterface, int i) {
- IconContextMenuItem item = (IconContextMenuItem) menuAdapter.getItem(i);
-
- if (clickHandler != null) {
- clickHandler.onClick(item.actionTag);
- }
- }
+ builder.setAdapter(menuAdapter, (dialoginterface, i) -> {
+ IconContextMenuItem item = (IconContextMenuItem) menuAdapter.getItem(i);
+ if (clickHandler != null)
+ clickHandler.onClick(item.actionTag);
});
builder.setInverseBackgroundForced(true);
-
AlertDialog dialog = builder.create();
dialog.setOnCancelListener(this);
dialog.setOnDismissListener(this);
@@ -117,7 +109,7 @@ public class IconContextMenu implements DialogInterface.OnCancelListener,
}
private void cleanup() {
- parentActivity.dismissDialog(dialogId);
+// parentActivity.dismissDialog(dialogId);
}
/**
@@ -131,7 +123,7 @@ public class IconContextMenu implements DialogInterface.OnCancelListener,
* Menu-like list adapter with icon
*/
protected class IconMenuAdapter extends BaseAdapter {
- private Context context = null;
+ private Context context;
private ArrayList mItems = new ArrayList();
@@ -193,6 +185,7 @@ public class IconContextMenu implements DialogInterface.OnCancelListener,
textView.setTag(item);
textView.setText(item.text);
textView.setCompoundDrawablesWithIntrinsicBounds(item.image, null, null, null);
+ textView.setTextColor(R.color.black);
return textView;
}
diff --git a/safeDispatch/src/main/java/com/safemobile/dispatch/LiveActivity.java b/safeDispatch/src/main/java/com/safemobile/dispatch/LiveActivity.java
index e8e3ca6..34d0e31 100644
--- a/safeDispatch/src/main/java/com/safemobile/dispatch/LiveActivity.java
+++ b/safeDispatch/src/main/java/com/safemobile/dispatch/LiveActivity.java
@@ -9,13 +9,19 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Configuration;
import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Matrix;
+import android.graphics.Paint;
+import android.graphics.Rect;
import android.graphics.Typeface;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.view.View;
import android.view.Window;
-import android.widget.AdapterView;
import android.widget.Button;
import android.widget.GridView;
import android.widget.ImageButton;
@@ -26,11 +32,13 @@ import android.widget.Toast;
import androidx.annotation.NonNull;
-import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
+import com.google.android.gms.maps.model.BitmapDescriptor;
+import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
+import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.safemobile.activities.AbstractLiveActivity;
import com.safemobile.activities.AbstractSDParentActivity;
@@ -94,6 +102,7 @@ public class LiveActivity extends AbstractLiveActivity implements OnMapReadyCall
//value poll
private double latPoll = 0;
private double lngPoll = 0;
+ private ArrayList markers = new ArrayList<>();
@Override
@@ -130,12 +139,11 @@ public class LiveActivity extends AbstractLiveActivity implements OnMapReadyCall
mapFragment.getMapAsync(this);
}
-
// create on vehicle long click menu
createIconContextMenu();
// image View for changing map type satellite or map
- ImageView changeMapTypeImageView = (ImageView) findViewById(R.id.changeMapType);
+ ImageView changeMapTypeImageView = findViewById(R.id.changeMapType);
changeMapTypeImageView.setOnClickListener(v -> {
if (googleMap.getMapType() == GoogleMap.MAP_TYPE_SATELLITE) {
changeMapTypeImageView.setImageResource(R.drawable.satellite);
@@ -146,7 +154,7 @@ public class LiveActivity extends AbstractLiveActivity implements OnMapReadyCall
}
});
- ImageView changeTrafficImageView = (ImageView) findViewById(R.id.changeTraffic);
+ ImageView changeTrafficImageView = findViewById(R.id.changeTraffic);
changeTrafficImageView.setOnClickListener(v -> {
if (googleMap.isTrafficEnabled()) {
changeTrafficImageView.setImageResource(R.drawable.traffic_off);
@@ -158,12 +166,12 @@ public class LiveActivity extends AbstractLiveActivity implements OnMapReadyCall
});
// change tab header font
- TextView textView1 = (TextView) findViewById(R.id.textView1);
+ TextView textView1 = findViewById(R.id.textView1);
textView1.setTypeface(Typeface.createFromAsset(getAssets(), "Sketch_Block.ttf"));
textView1.setTextSize(24);
// get grid view and set empty data adapter
- gridVehicle = (GridView) findViewById(R.id.gridVehicle);
+ gridVehicle = findViewById(R.id.gridVehicle);
if (AppParams.DEMO) {
disabledVehicles = new ArrayList<>();
@@ -185,14 +193,16 @@ public class LiveActivity extends AbstractLiveActivity implements OnMapReadyCall
threadUI.start();
});
-
// get vehicle menu creation
- gridVehicle.setOnItemLongClickListener(itemLongClickHandler);
+ gridVehicle.setOnItemLongClickListener((adapterView, view, i, l) -> {
+ contextMenuPosition = position;
+ iconContextMenu.createMenu(getString(R.string.options)).show();
+ return true;
+ });
-
- LinearLayout slideLayout = (LinearLayout) findViewById(R.id.slidelayout);
- ImageView slideLayoutImageView = (ImageView) findViewById(R.id.slideLayoutImage);
- LinearLayout linearLayoutVehicles = (LinearLayout) findViewById(R.id.layoutBig);
+ LinearLayout slideLayout = findViewById(R.id.slidelayout);
+ ImageView slideLayoutImageView = findViewById(R.id.slideLayoutImage);
+ LinearLayout linearLayoutVehicles = findViewById(R.id.layoutBig);
slideLayout.setOnClickListener(v -> {
if (showVehicle) {
linearLayoutVehicles.setVisibility(View.GONE);
@@ -205,7 +215,7 @@ public class LiveActivity extends AbstractLiveActivity implements OnMapReadyCall
}
});
- imageViewCheckAll = (ImageButton) findViewById(R.id.imageCheckAll);
+ imageViewCheckAll = findViewById(R.id.imageCheckAll);
imageViewCheckAll.setSelected(false);
imageViewCheckAll.setOnClickListener(arg0 -> {
for (int i = 0; i < displayedVehicles.size(); i++)
@@ -223,7 +233,7 @@ public class LiveActivity extends AbstractLiveActivity implements OnMapReadyCall
Enumeration keyList = getParentTab().getSuperVehHash().keys();
while (keyList.hasMoreElements()) {
- (Objects.requireNonNull(getParentTab().getSuperVehHash().get((long) keyList.nextElement()))).needUpdate = true;
+ (Objects.requireNonNull(getParentTab().getSuperVehHash().get(keyList.nextElement()))).needUpdate = true;
}
// change button title
@@ -247,7 +257,7 @@ public class LiveActivity extends AbstractLiveActivity implements OnMapReadyCall
displayVehicle(true, LAT_OUTLIMIT, LNG_OUTLIMIT);
});
- displayButton = (Button) findViewById(R.id.buttonDisplay);
+ displayButton = findViewById(R.id.buttonDisplay);
displayButton.setText(getString(R.string.displayAll));
@@ -259,7 +269,7 @@ public class LiveActivity extends AbstractLiveActivity implements OnMapReadyCall
Enumeration keyList = getParentTab().getSuperVehHash().keys();
while (keyList.hasMoreElements())
- (Objects.requireNonNull(getParentTab().getSuperVehHash().get((long) keyList.nextElement()))).needUpdate = true;
+ (Objects.requireNonNull(getParentTab().getSuperVehHash().get(keyList.nextElement()))).needUpdate = true;
// change button title
if (displayButton.getText().toString().equals(getString(R.string.displayAll))) {
@@ -297,11 +307,8 @@ public class LiveActivity extends AbstractLiveActivity implements OnMapReadyCall
@Override
public void onMapReady(@NonNull GoogleMap googleMap) {
this.googleMap = googleMap;
-
- // Add a marker in Sydney and move the camera
- LatLng sydney = new LatLng(-34, 151);
- this.googleMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
- this.googleMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));
+ GoogleMapsInfoBubble infoBubble = new GoogleMapsInfoBubble(getLayoutInflater(), this, getParentTab().getSuperVehHash());
+ this.googleMap.setInfoWindowAdapter(infoBubble);
}
@@ -433,36 +440,101 @@ public class LiveActivity extends AbstractLiveActivity implements OnMapReadyCall
});
}
- /**
- * create context menu
- */
- @Override
- public Dialog onCreateDialog(int id) {
- if (id == 1) {
- return iconContextMenu.createMenu(getString(R.string.options));
- }
- return super.onCreateDialog(id);
- }
-
-
- /* list item long click handler
- * used to show the context menu
- */
- private final AdapterView.OnItemLongClickListener itemLongClickHandler = ((parent, view, position, id) -> {
- // save position
- contextMenuPosition = position;
- showDialog(1);
- return true;
- });
-
public void displayVehicle(boolean withZoom, double latZoom, double lngZoom) {
- //TODO: add makers for vehicles
+ if (googleMap != null) {
+ String openWindow = "";
+ for (Marker marker : markers) {
+ if (marker.isInfoWindowShown()) {
+ openWindow = marker.getTitle();
+ }
+ }
+ googleMap.clear();
+
+ for (int i = 0; i < displayedVehicles.size(); i++) {
+ if (displayedVehicles.get(i)) {
+ SuperVehicle tmpSuper = getParentTab().getSuperVehHash().get(Long.valueOf(liveVehicle.get(i).imei));
+
+ if (tmpSuper != null) {
+ LatLng newLocation = new LatLng(tmpSuper.lat, tmpSuper.lng);
+ MarkerOptions markerOptions = new MarkerOptions().position(newLocation).title(liveVehicle.get(i).imei);
+
+ BitmapDescriptor markerIcon = getProperBitmap(tmpSuper.getLargeIcon(), tmpSuper.name);
+ markerOptions.icon(markerIcon);
+
+ Marker marker = this.googleMap.addMarker(markerOptions);
+ if (openWindow.equals(marker.getTitle()))
+ marker.showInfoWindow();
+
+ markers.add(marker);
+ }
+ }
+ }
+ }
}
public void showOpenedBalloon(boolean demo) {
//TODO: add show balloon
}
+ private BitmapDescriptor getProperBitmap(int largeIcon, String text) {
+ Bitmap bitmap = BitmapFactory.decodeResource(getResources(), largeIcon);
+ Bitmap textBitmap = getTextAsDrawable(this, text);
+ Bitmap b3 = overlay(bitmap, textBitmap);
+ return BitmapDescriptorFactory.fromBitmap(b3);
+ }
+
+ public static Bitmap overlay(Bitmap bmp1, Bitmap bmp2) {
+ int maxWidth = Math.max(bmp1.getWidth(), bmp2.getWidth());
+
+ Bitmap bmOverlay = Bitmap.createBitmap(maxWidth, bmp1.getHeight() + bmp2.getHeight(), bmp1.getConfig());
+ Canvas canvas = new Canvas(bmOverlay);
+ canvas.drawBitmap(bmp1, new Matrix(), null);
+ canvas.drawBitmap(bmp2, 0, bmp1.getHeight(), null);
+ bmp1.recycle();
+ bmp2.recycle();
+ return bmOverlay;
+ }
+
+ public Bitmap getTextAsDrawable(Context context, String text) {
+ Typeface tf = Typeface.create("Helvetica", Typeface.BOLD);
+
+ Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ paint.setColor(Color.WHITE);
+ paint.setTypeface(tf);
+ paint.setTextSize(convertToPixels(context, 16));
+
+ Rect textRect = new Rect();
+ paint.getTextBounds(text, 0, text.length(), textRect);
+
+ Bitmap bitmap = Bitmap.createBitmap(textRect.width(), textRect.height() + 5,
+ Bitmap.Config.ARGB_8888);
+
+ Canvas canvas = new Canvas(bitmap);
+ paint.setColor(getResources().getColor(R.color.cardview_dark_background));
+ canvas.drawRect(0, 0, bitmap.getWidth(), bitmap.getHeight(), paint);
+
+
+ float scale = context.getResources().getDisplayMetrics().density;
+ // text color - #3D3D3D
+ paint.setColor(Color.rgb(255, 255, 255));
+ // text size in pixels
+
+ // draw text to the Canvas center
+ Rect bounds = new Rect();
+ paint.getTextBounds(text, 0, text.length(), bounds);
+ int x = (bitmap.getWidth() - bounds.width()) / 2;
+ int y = (bitmap.getHeight() + bounds.height()) / 2;
+
+ canvas.drawText(text, x, y, paint);
+
+ return bitmap;
+ }
+
+ public int convertToPixels(Context context, int nDP) {
+ final float conversionScale = context.getResources().getDisplayMetrics().density;
+ return (int) ((nDP * conversionScale) + 0.5f);
+ }
+
public void showLoadingDialog(String message) {
loadingDialog = new Dialog(context);
loadingDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
@@ -470,9 +542,9 @@ public class LiveActivity extends AbstractLiveActivity implements OnMapReadyCall
loadingDialog.setCancelable(true);
loadingDialog.setCanceledOnTouchOutside(false);
- Button cancel = (Button) loadingDialog.findViewById(R.id.buttonCancel);
+ Button cancel = loadingDialog.findViewById(R.id.buttonCancel);
cancel.setVisibility(View.GONE);
- TextView textView1 = (TextView) loadingDialog.findViewById(R.id.textView1);
+ TextView textView1 = loadingDialog.findViewById(R.id.textView1);
textView1.setText(message);
loadingDialog.show();
@@ -501,8 +573,7 @@ public class LiveActivity extends AbstractLiveActivity implements OnMapReadyCall
disabledVehicles.add(!veh.status);
// add vehicle to hash Table according to driver_id
- if (tableHashOverlay.get((int) veh.driver_id) == null) // if doesn't exist
- {
+ if (tableHashOverlay.get((int) veh.driver_id) == null) {
ArrayList array = new ArrayList<>();
SuperVehicle superVehicle = new SuperVehicle(veh.sc_id, veh.imei, veh.lp, veh.name, veh.driver_id, veh.time_route, veh.GPS_reporting_interval, veh.is_stolen);
array.add(superVehicle);
@@ -519,7 +590,6 @@ public class LiveActivity extends AbstractLiveActivity implements OnMapReadyCall
}
// set adapter
-
adapter = new VehiclesGridViewAdapter(activity, context, list, disabledVehicles);
adapter.notifyDataSetChanged();
@@ -538,7 +608,6 @@ public class LiveActivity extends AbstractLiveActivity implements OnMapReadyCall
// show vehicles in gridView
private void updateResultsUI() {
gridVehicle.setAdapter(adapter);
-
try {
// hide loading dialog
loadingDialog.cancel();
@@ -576,7 +645,6 @@ public class LiveActivity extends AbstractLiveActivity implements OnMapReadyCall
pollReceived(position,lat,lng);
}
-
public void updatePosition(int pos) {
contextMenuPosition = pos;
}
@@ -598,11 +666,9 @@ public class LiveActivity extends AbstractLiveActivity implements OnMapReadyCall
final Runnable updateOptionsRUN = this::updateOptionsUI;
private void updateOptionsUI() {
-
SM.Debug("REFRESHDisableEnable" + (Boolean.TRUE.equals(disabledVehicles.get(contextMenuPosition)) ? "true" : "false"));
// change Enable/Disable in adapter
adapter.changeDisabled(contextMenuPosition, disabledVehicles.get(contextMenuPosition));
-
}
/**
@@ -692,7 +758,6 @@ public class LiveActivity extends AbstractLiveActivity implements OnMapReadyCall
// zone and channel change intent
IntentFilter intentFilter = new IntentFilter(OperationCodes.UNIT_STATUS_UPDATE + "");
this.registerReceiver(mReceiver, intentFilter);
-
}
//The BroadcastReceiver that listens for Notification broadcasts
@@ -723,4 +788,9 @@ public class LiveActivity extends AbstractLiveActivity implements OnMapReadyCall
}
}
};
+
+ @Override
+ public GoogleMap getMap() {
+ return googleMap;
+ }
}
\ No newline at end of file
diff --git a/safeDispatch/src/main/java/com/safemobile/dispatch/TabLayoutActivity.java b/safeDispatch/src/main/java/com/safemobile/dispatch/TabLayoutActivity.java
index 5abc586..ac25ba6 100644
--- a/safeDispatch/src/main/java/com/safemobile/dispatch/TabLayoutActivity.java
+++ b/safeDispatch/src/main/java/com/safemobile/dispatch/TabLayoutActivity.java
@@ -265,11 +265,11 @@ public class TabLayoutActivity extends AbstractSDParentActivity{
tabHost = getTabHost(); // The activity TabHost
tabHost.setTag("Tab Panel");
- tabWidget = (TabWidget) findViewById(android.R.id.tabs);
+ tabWidget = findViewById(android.R.id.tabs);
tabWidget.setVisibility(View.GONE);
- intent = new Intent[7];
- tabspecs = new TabSpec[7];
+ intent = new Intent[8];
+ tabspecs = new TabSpec[8];
// add live tab
try
@@ -288,23 +288,6 @@ public class TabLayoutActivity extends AbstractSDParentActivity{
.setContent(intent[0]);
}
- // add history tab
- try
- {
- //intent[1] = new Intent(context, HistoryActivity.class);
- //tabspecs[1] = tabHost.newTabSpec("History")
- // .setIndicator("History", res.getDrawable(R.drawable.ic_tab_history_selected))
- // .setContent(intent[1]);
- }
- catch(NoClassDefFoundError e)
- {
- // exception when GoogleApi not exists
- //intent[1] = new Intent(context, AbstractEmptyActivity.class);
- //tabspecs[1] = tabHost.newTabSpec("History")
- // .setIndicator("History", res.getDrawable(R.drawable.ic_tab_history_selected))
- // .setContent(intent[1]);
- }
-
// add text tab
intent[1] = new Intent(context, MessagesActivity.class);
tabspecs[1] = tabHost.newTabSpec("Text")
@@ -340,6 +323,21 @@ public class TabLayoutActivity extends AbstractSDParentActivity{
tabspecs[6] = tabHost.newTabSpec("SafeMobile")
.setIndicator("SafeMobile", res.getDrawable(AppParams.DEMO ? R.drawable.icon_demo : R.drawable.ic_launcher))
.setContent(intent[6]);
+
+ // add history tab
+ try
+ {
+ intent[7] = new Intent(context, HistoryActivity.class);
+ tabspecs[7] = tabHost.newTabSpec("History")
+ .setIndicator("History", res.getDrawable(R.drawable.ic_tab_history_selected))
+ .setContent(intent[7]);
+ } catch(NoClassDefFoundError e) {
+// exception when GoogleApi not exists
+ intent[7] = new Intent(context, AbstractEmptyActivity.class);
+ tabspecs[7] = tabHost.newTabSpec("History")
+ .setIndicator("History", res.getDrawable(R.drawable.ic_tab_history_selected))
+ .setContent(intent[1]);
+ }
// add tab in tabHost
// for(int i=0;i<7;i++
@@ -353,58 +351,61 @@ public class TabLayoutActivity extends AbstractSDParentActivity{
imageViewSlideMenu = (ImageView) findViewById(R.id.imageViewSlideMenu);
// get Live Button
- buttonLive = (ImageButton) findViewById(R.id.buttonLive);
- buttonLive.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- if(!buttonLive.isSelected())
- {
- // select button
- buttonLive.setSelected(true);
- // deselect other buttons
- buttonAlarms.setSelected(false);
- buttonHistory.setSelected(false);
- buttonRadio.setSelected(false);
- buttonRecordings.setSelected(false);
- buttonSetup.setSelected(false);
- buttonText.setSelected(false);
- // select tab
- tabHost.setCurrentTabByTag("Live");
- AppParams.crtTab = AppParams.Tabs.live;
- }
+ buttonLive = findViewById(R.id.buttonLive);
+ buttonLive.setOnClickListener(v -> {
+ if (!buttonLive.isSelected()) {
+ // select button
+ buttonLive.setSelected(true);
+ // deselect other buttons
+ buttonAlarms.setSelected(false);
+ buttonHistory.setSelected(false);
+ buttonRadio.setSelected(false);
+ buttonRecordings.setSelected(false);
+ buttonSetup.setSelected(false);
+ buttonText.setSelected(false);
+ // select tab
+ tabHost.setCurrentTabByTag("Live");
+ AppParams.crtTab = AppParams.Tabs.live;
}
});
// get History Button
- buttonHistory = (ImageButton) findViewById(R.id.buttonHistory);
- buttonHistory.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- if(!buttonHistory.isSelected())
- {
- // select button
- buttonHistory.setSelected(true);
- // deselect other buttons
- buttonAlarms.setSelected(false);
- buttonLive.setSelected(false);
- buttonRadio.setSelected(false);
- buttonRecordings.setSelected(false);
- buttonSetup.setSelected(false);
- buttonText.setSelected(false);
- // select tab
- tabHost.setCurrentTabByTag("History");
- AppParams.crtTab = AppParams.Tabs.history;
- }
+ buttonHistory = findViewById(R.id.buttonHistory);
+ buttonHistory.setOnClickListener(v -> {
+ if (!buttonHistory.isSelected()) {
+ // select button
+ buttonHistory.setSelected(true);
+ // deselect other buttons
+ buttonAlarms.setSelected(false);
+ buttonLive.setSelected(false);
+ buttonRadio.setSelected(false);
+ buttonRecordings.setSelected(false);
+ buttonSetup.setSelected(false);
+ buttonText.setSelected(false);
+ // select tab
+ tabHost.setCurrentTabByTag("History");
+ AppParams.crtTab = AppParams.Tabs.history;
}
});
// get Text Button
- buttonText= (ImageButton) findViewById(R.id.buttonText);
- buttonText.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- if(!buttonText.isSelected())
- {
+ buttonText= findViewById(R.id.buttonText);
+ buttonText.setOnClickListener(v -> {
+ if (!buttonText.isSelected()) {
+ // select button
+ buttonText.setSelected(true);
+ // deselect other buttons
+ buttonAlarms.setSelected(false);
+ buttonLive.setSelected(false);
+ buttonRadio.setSelected(false);
+ buttonRecordings.setSelected(false);
+ buttonSetup.setSelected(false);
+ buttonHistory.setSelected(false);
+ // select tab
+ tabHost.setCurrentTabByTag("Text");
+ AppParams.crtTab = AppParams.Tabs.message;
+
+ if (AppParams.DEMO && messageActivity.allVehicle.size()== 0) {
// select button
buttonText.setSelected(true);
// deselect other buttons
@@ -418,8 +419,7 @@ public class TabLayoutActivity extends AbstractSDParentActivity{
tabHost.setCurrentTabByTag("Text");
AppParams.crtTab = AppParams.Tabs.message;
- if(AppParams.DEMO && messageActivity.allVehicle.size()== 0)
- {
+ if (AppParams.DEMO && messageActivity.allVehicle.size()== 0) {
messageActivity.UpdateVehs(getAllVehicle());
messageActivity.UpdateSMS(listSMS);
}
@@ -609,24 +609,21 @@ public class TabLayoutActivity extends AbstractSDParentActivity{
});
// get About Button
- buttonLogo = (ImageButton) findViewById(R.id.buttonLogo);
- buttonLogo.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- // create dialog
- final Dialog dialog = new Dialog(context);
- dialog.setTitle(AppParams.DEMO ? getString(R.string.app_name_demo) : getString(R.string.app_name));
- dialog.setContentView(R.layout.dialog);
- ImageView image = (ImageView) dialog.findViewById(R.id.image);
- image.setImageResource(AppParams.DEMO ? R.drawable.icon_demo : R.drawable.ic_launcher);
- TextView text = (TextView) dialog.findViewById(R.id.text);
- TextView text2 = (TextView) dialog.findViewById(R.id.text2);
- text.setText(getString(R.string.version) + "1.0.8");
- text2.setText(getString(R.string.email) + ": support@safemobile.com");
- dialog.setCancelable(true);
- dialog.setCanceledOnTouchOutside(true);
- dialog.show();
- }
+ buttonLogo = findViewById(R.id.buttonLogo);
+ buttonLogo.setOnClickListener(v -> {
+ // create dialog
+ final Dialog dialog = new Dialog(context);
+ dialog.setTitle(AppParams.DEMO ? getString(R.string.app_name_demo) : getString(R.string.app_name));
+ dialog.setContentView(R.layout.dialog);
+ ImageView image = dialog.findViewById(R.id.image);
+ image.setImageResource(AppParams.DEMO ? R.drawable.icon_demo : R.drawable.ic_launcher);
+ TextView text = dialog.findViewById(R.id.text);
+ TextView text2 = dialog.findViewById(R.id.text2);
+ text.setText(getString(R.string.version) + "1.0.8");
+ text2.setText(getString(R.string.email) + ": support@safemobile.com");
+ dialog.setCancelable(true);
+ dialog.setCanceledOnTouchOutside(true);
+ dialog.show();
});
imageViewClose.setOnTouchListener(new OnTouchListener() {
@@ -1234,36 +1231,28 @@ public class TabLayoutActivity extends AbstractSDParentActivity{
GPSmsg GPSPos= new GPSmsg(msg);
//SM.Debug("Got new GPS pos data:" + GPSPos.data);
-
- if(getSuperVehHash().get(GPSPos.gpsValue.imei) != null)
- {
- ((SuperVehicle) getSuperVehHash().get(GPSPos.gpsValue.imei)).SetNewPosition(GPSPos.gpsValue.lat, GPSPos.gpsValue.lng, GPSPos.gpsValue.timeGMT, GPSPos.gpsValue.speed);
+
+ if (getSuperVehHash().get(GPSPos.gpsValue.imei) != null) {
+ getSuperVehHash().get(GPSPos.gpsValue.imei).SetNewPosition(GPSPos.gpsValue.lat, GPSPos.gpsValue.lng, GPSPos.gpsValue.timeGMT, GPSPos.gpsValue.speed);
- if(getSuperVehHash().get(GPSPos.gpsValue.imei).needUpdate)
- {
-
- //list for live
- if(AppParams.crtTab == AppParams.Tabs.live)
- {
- //SM.Debug("+++++ duda +++++");
- SM.Debug("currentActivity instanceof LiveActivity");
- try
- {
- if(liveActivity != null)
- liveActivity.refreshMap();
- }
- catch (Exception ex)
- {
- SM.Debug("Error load hash:"+ex.toString());
- }
- }
- }
+ if (getSuperVehHash().get(GPSPos.gpsValue.imei).needUpdate) {
+ //list for live
+ if (AppParams.crtTab == AppParams.Tabs.live) {
+ //SM.Debug("+++++ duda +++++");
+ SM.Debug("currentActivity instanceof LiveActivity");
+ try {
+ if(liveActivity != null)
+ liveActivity.refreshMap();
+ } catch (Exception ex) {
+ SM.Debug("Error load hash:"+ex.toString());
+ }
+ }
+ }
}
}
@Override
- public void onPollReceived(TCPEvent event)
- {
+ public void onPollReceived(TCPEvent event) {
SM.Debug("Got POLL GPS message");
TCPmsg msg= event.msg();
GPSmsg GPSPos= new GPSmsg(msg);
@@ -1271,13 +1260,12 @@ public class TabLayoutActivity extends AbstractSDParentActivity{
setMess("LAT:"+Double.toString(GPSPos.gpsValue.lat)+" LNG:"+Double.toString(GPSPos.gpsValue.lng));
SM.Debug("Got new Poll pos data:" + GPSPos.data);
- if(getSuperVehHash().get(GPSPos.gpsValue.imei) != null)
- {
+
+ if(getSuperVehHash().get(GPSPos.gpsValue.imei) != null) {
((SuperVehicle) getSuperVehHash().get(GPSPos.gpsValue.imei)).SetNewPosition(GPSPos.gpsValue.lat, GPSPos.gpsValue.lng, GPSPos.gpsValue.timeGMT, GPSPos.gpsValue.speed);
//if is not check i need to force check to put on the map
Boolean forceChecked =false;
- if (!getSuperVehHash().get(GPSPos.gpsValue.imei).needUpdate)
- {
+ if (!getSuperVehHash().get(GPSPos.gpsValue.imei).needUpdate) {
getSuperVehHash().get(GPSPos.gpsValue.imei).needUpdate =true;
forceChecked =true;
}
@@ -1468,28 +1456,19 @@ public class TabLayoutActivity extends AbstractSDParentActivity{
}
// if tab is not TextTab
- if(tabHost.getCurrentTab() != 2)
- {
+ if(tabHost.getCurrentTab() != 2) {
myHandler.post(UpdateResults);
//mHandler.dispatchMessage(new Message());
- }
- else
- myHandler.post(new Runnable() {
-
- @Override
- public void run() {
- // create Notification
- createNotification(AppParams.messageNotif);
- }
+ } else
+ myHandler.post(() -> {
+ // create Notification
+ createNotification(AppParams.messageNotif);
});
//list for SMS
- if(AppParams.crtTab == AppParams.Tabs.message && messageActivity!= null)
- {
+ if(AppParams.crtTab == AppParams.Tabs.message && messageActivity!= null) {
SM.Debug("currentActivity instanceof MessagesActivity - NewSMS | " + tempArr[0] + " | " + tempArr[1]);
messageActivity.NewSMS(tempArr[0], tempArr[1], time);
}
-
-
}
@Override
@@ -1523,15 +1502,13 @@ public class TabLayoutActivity extends AbstractSDParentActivity{
@Override
public void onLastPositionsReceived(TCPEvent event) {
TCPmsg msg= event.msg();
- SM.Debug("Got lastpos");
- //SM.Debug("Got lastpos :" + msg.allData);
-
+ SM.Debug("Got last pos");
+
LastPosmsg lastPos= new LastPosmsg(msg);
//SM.Debug("Got LastPost msg.data:" + msg.data);
- for(LastPos posMsg: lastPos.PosList)
- {
+ for(LastPos posMsg: lastPos.PosList) {
if(getSuperVehHash().get(posMsg.imei) != null)
- ((SuperVehicle) getSuperVehHash().get(posMsg.imei)).SetDataFromLastPos(posMsg.lat, posMsg.lng, posMsg.timeGMT, posMsg.speed, posMsg.Address, posMsg.isON);
+ getSuperVehHash().get(posMsg.imei).SetDataFromLastPos(posMsg.lat, posMsg.lng, posMsg.timeGMT, posMsg.speed, posMsg.Address, posMsg.isON);
}
}
diff --git a/safeDispatch/src/main/res/layout/tabhistory.xml b/safeDispatch/src/main/res/layout/tabhistory.xml
index 10a0b62..d4536fc 100644
--- a/safeDispatch/src/main/res/layout/tabhistory.xml
+++ b/safeDispatch/src/main/res/layout/tabhistory.xml
@@ -5,337 +5,328 @@
android:id="@+id/tab1Layout" android:orientation="horizontal"
style="?bg">
-
+
-
+
-
-
+
+
-
+
-
+
-
+
-
+
-
+
-
-
-
-
-
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
-
+ android:id="@+id/LayoutSpinner"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:orientation="vertical"
+ android:paddingTop="10dp"
+ android:gravity="top"
+ android:layout_weight="1">
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
-
-
-
-
-
-
+
+
\ No newline at end of file
diff --git a/safeDispatch/src/main/res/layout/tabpanel.xml b/safeDispatch/src/main/res/layout/tabpanel.xml
index 08a21bc..4dff142 100644
--- a/safeDispatch/src/main/res/layout/tabpanel.xml
+++ b/safeDispatch/src/main/res/layout/tabpanel.xml
@@ -5,90 +5,70 @@
android:orientation="vertical" >
-
-
-
-
-
-
-
-
-
+ android:id="@+id/linearLayout1"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:background="#000000">
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
+
+ android:padding="3dp">
-
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal">
+
-
\ No newline at end of file
diff --git a/safeDispatch/src/main/res/values-de/strings.xml b/safeDispatch/src/main/res/values-de/strings.xml
index caf053d..c0fd0fc 100644
--- a/safeDispatch/src/main/res/values-de/strings.xml
+++ b/safeDispatch/src/main/res/values-de/strings.xml
@@ -232,4 +232,7 @@
- German
- Romanian
+
+ %1$d mph
+
\ No newline at end of file
diff --git a/safeDispatch/src/main/res/values-es/strings.xml b/safeDispatch/src/main/res/values-es/strings.xml
index 6f0fd3c..c8269bb 100644
--- a/safeDispatch/src/main/res/values-es/strings.xml
+++ b/safeDispatch/src/main/res/values-es/strings.xml
@@ -236,4 +236,7 @@
- Spanish
- Russian
+
+ %1$d mph
+
\ No newline at end of file
diff --git a/safeDispatch/src/main/res/values-ro/strings.xml b/safeDispatch/src/main/res/values-ro/strings.xml
index d1a0dff..168d4fb 100644
--- a/safeDispatch/src/main/res/values-ro/strings.xml
+++ b/safeDispatch/src/main/res/values-ro/strings.xml
@@ -233,4 +233,7 @@
- Turca
- Romana
+
+ %1$d mph
+
\ No newline at end of file
diff --git a/safeDispatch/src/main/res/values-tr/strings.xml b/safeDispatch/src/main/res/values-tr/strings.xml
index 21068cd..b7fd8ac 100644
--- a/safeDispatch/src/main/res/values-tr/strings.xml
+++ b/safeDispatch/src/main/res/values-tr/strings.xml
@@ -232,4 +232,7 @@
- German
- Romanian
+
+ %1$d mph
+
\ No newline at end of file
diff --git a/safeDispatch/src/main/res/values/strings.xml b/safeDispatch/src/main/res/values/strings.xml
index 6630330..f415089 100644
--- a/safeDispatch/src/main/res/values/strings.xml
+++ b/safeDispatch/src/main/res/values/strings.xml
@@ -254,4 +254,8 @@
NewLiveActivity
GoogleMapsActivity
+
+
+ %1$d mph
+
\ No newline at end of file