2022-03-14 09:53:00 +00:00
|
|
|
package com.safemobile.dispatch;
|
|
|
|
|
|
|
|
import android.app.Activity;
|
|
|
|
import android.app.AlertDialog;
|
|
|
|
import android.app.Dialog;
|
|
|
|
import android.content.BroadcastReceiver;
|
|
|
|
import android.content.Context;
|
|
|
|
import android.content.Intent;
|
|
|
|
import android.content.IntentFilter;
|
|
|
|
import android.content.res.Configuration;
|
|
|
|
import android.content.res.Resources;
|
2022-03-15 12:45:18 +00:00
|
|
|
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;
|
2022-03-14 09:53:00 +00:00
|
|
|
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.Button;
|
|
|
|
import android.widget.GridView;
|
|
|
|
import android.widget.ImageButton;
|
|
|
|
import android.widget.ImageView;
|
|
|
|
import android.widget.LinearLayout;
|
|
|
|
import android.widget.TextView;
|
|
|
|
import android.widget.Toast;
|
|
|
|
|
|
|
|
import androidx.annotation.NonNull;
|
|
|
|
|
|
|
|
import com.google.android.gms.maps.GoogleMap;
|
|
|
|
import com.google.android.gms.maps.OnMapReadyCallback;
|
|
|
|
import com.google.android.gms.maps.SupportMapFragment;
|
2022-03-15 12:45:18 +00:00
|
|
|
import com.google.android.gms.maps.model.BitmapDescriptor;
|
|
|
|
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
|
2022-03-14 09:53:00 +00:00
|
|
|
import com.google.android.gms.maps.model.LatLng;
|
2022-03-16 12:41:05 +00:00
|
|
|
import com.google.android.gms.maps.model.Marker;
|
2022-03-14 09:53:00 +00:00
|
|
|
import com.google.android.gms.maps.model.MarkerOptions;
|
|
|
|
import com.safemobile.activities.AbstractLiveActivity;
|
|
|
|
import com.safemobile.activities.AbstractSDParentActivity;
|
|
|
|
import com.safemobile.adapters.VehiclesGridViewAdapter;
|
|
|
|
import com.safemobile.lib.AppParams;
|
|
|
|
import com.safemobile.lib.OperationCodes;
|
|
|
|
import com.safemobile.lib.SM;
|
|
|
|
import com.safemobile.lib.SuperVehicle;
|
|
|
|
import com.safemobile.lib.Vehicle;
|
|
|
|
|
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.Enumeration;
|
|
|
|
import java.util.HashMap;
|
|
|
|
import java.util.Locale;
|
|
|
|
import java.util.Objects;
|
|
|
|
|
|
|
|
public class LiveActivity extends AbstractLiveActivity implements OnMapReadyCallback {
|
|
|
|
|
|
|
|
private GoogleMap googleMap;
|
|
|
|
|
|
|
|
/* Context Menu */
|
|
|
|
private static final int MENU_ENABLE = 150;
|
|
|
|
private static final int MENU_DISABLE = 151;
|
|
|
|
private static final int MENU_REMOTE = 161;
|
|
|
|
private static final int MENU_POLL = 154;
|
|
|
|
private static final double LAT_OUTLIMIT = 91;
|
|
|
|
private static final double LNG_OUTLIMIT = 181;
|
|
|
|
private IconContextMenu iconContextMenu = null;
|
|
|
|
|
|
|
|
/* Dialog */
|
|
|
|
private Dialog loadingDialog;
|
|
|
|
|
|
|
|
// Need handler for callbacks to the UI thread
|
|
|
|
private final Handler myHandler = new Handler(Looper.getMainLooper());
|
|
|
|
private Thread threadUI;
|
|
|
|
|
|
|
|
/* Misc */
|
|
|
|
private Context context;
|
|
|
|
private Resources res;
|
|
|
|
private Activity activity;
|
|
|
|
|
|
|
|
/* Visual Elements */
|
|
|
|
private ImageButton imageViewCheckAll;
|
|
|
|
private Button displayButton;
|
|
|
|
private boolean isFirstRun = true;
|
|
|
|
private boolean isFirstMap = true;
|
|
|
|
private boolean isAck = false;
|
|
|
|
private boolean showVehicle = true;
|
|
|
|
private int contextMenuPosition;
|
|
|
|
private int vehStatus;
|
|
|
|
private int position; // vehStatus = vehicle status received from apps
|
|
|
|
|
|
|
|
/* Live Vehicle GridView */
|
|
|
|
private GridView gridVehicle;
|
|
|
|
private ArrayList<Vehicle> liveVehicle = new ArrayList<>();
|
|
|
|
private ArrayList<Boolean> displayedVehicles = new ArrayList<>();
|
|
|
|
private ArrayList<Boolean> disabledVehicles = new ArrayList<>();
|
|
|
|
private VehiclesGridViewAdapter adapter;
|
|
|
|
private final HashMap<Integer, ArrayList<SuperVehicle>> tableHashOverlay = new HashMap<>();
|
|
|
|
|
|
|
|
//value poll
|
|
|
|
private double latPoll = 0;
|
|
|
|
private double lngPoll = 0;
|
2022-03-16 12:41:05 +00:00
|
|
|
private ArrayList<Marker> markers = new ArrayList<>();
|
2022-03-14 09:53:00 +00:00
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void onCreate(Bundle savedInstanceState) {
|
|
|
|
super.onCreate(savedInstanceState);
|
|
|
|
this.setSavedInstanceState(savedInstanceState);
|
|
|
|
// get parentTab
|
|
|
|
setParentTab((AbstractSDParentActivity) getParent());
|
|
|
|
try {
|
2022-03-23 11:07:40 +00:00
|
|
|
((TabLayoutActivity) getParentTab()).setLiveActivity(this);
|
2022-03-14 09:53:00 +00:00
|
|
|
} catch (Exception ignored) {
|
|
|
|
// ignored
|
|
|
|
}
|
|
|
|
context = this;
|
|
|
|
activity = this;
|
|
|
|
res = getResources();
|
|
|
|
|
|
|
|
Locale locale = new Locale(AppParams.LANGUAGETMP);
|
|
|
|
Locale.setDefault(locale);
|
|
|
|
Configuration config = new Configuration();
|
|
|
|
config.locale = locale;
|
|
|
|
getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());
|
|
|
|
|
|
|
|
// get mapView only when creating first time
|
|
|
|
if (isFirstMap) {
|
|
|
|
setContentView(R.layout.tablive);
|
|
|
|
isFirstMap = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
|
|
|
|
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
|
|
|
|
.findFragmentById(R.id.map);
|
|
|
|
if (mapFragment != null) {
|
|
|
|
mapFragment.getMapAsync(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
// create on vehicle long click menu
|
|
|
|
createIconContextMenu();
|
|
|
|
|
|
|
|
// image View for changing map type satellite or map
|
2022-03-16 12:32:28 +00:00
|
|
|
ImageView changeMapTypeImageView = findViewById(R.id.changeMapType);
|
2022-03-14 09:53:00 +00:00
|
|
|
changeMapTypeImageView.setOnClickListener(v -> {
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2022-03-16 12:32:28 +00:00
|
|
|
ImageView changeTrafficImageView = findViewById(R.id.changeTraffic);
|
2022-03-14 09:53:00 +00:00
|
|
|
changeTrafficImageView.setOnClickListener(v -> {
|
|
|
|
if (googleMap.isTrafficEnabled()) {
|
|
|
|
changeTrafficImageView.setImageResource(R.drawable.traffic_off);
|
|
|
|
googleMap.setTrafficEnabled(false);
|
|
|
|
} else {
|
|
|
|
changeTrafficImageView.setImageResource(R.drawable.traffic);
|
|
|
|
googleMap.setTrafficEnabled(true);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
// change tab header font
|
2022-03-16 12:32:28 +00:00
|
|
|
TextView textView1 = findViewById(R.id.textView1);
|
2022-03-14 09:53:00 +00:00
|
|
|
textView1.setTypeface(Typeface.createFromAsset(getAssets(), "Sketch_Block.ttf"));
|
|
|
|
textView1.setTextSize(24);
|
|
|
|
|
|
|
|
// get grid view and set empty data adapter
|
2022-03-16 12:32:28 +00:00
|
|
|
gridVehicle = findViewById(R.id.gridVehicle);
|
2022-03-14 09:53:00 +00:00
|
|
|
|
|
|
|
if (AppParams.DEMO) {
|
|
|
|
disabledVehicles = new ArrayList<>();
|
2022-03-15 13:51:30 +00:00
|
|
|
for (Vehicle veh : getParentTab().getAllVehicle())
|
2022-03-14 09:53:00 +00:00
|
|
|
disabledVehicles.add(!veh.status);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-03-15 13:51:30 +00:00
|
|
|
adapter = new VehiclesGridViewAdapter(activity, context, getParentTab().getAllVehicle(), disabledVehicles);
|
2022-03-14 09:53:00 +00:00
|
|
|
adapter.notifyDataSetChanged();
|
|
|
|
gridVehicle.setAdapter(adapter);
|
|
|
|
|
|
|
|
// get vehicle display click
|
|
|
|
gridVehicle.setOnItemClickListener((parent, view, position, id) -> {
|
|
|
|
threadUI = new Thread(() -> {
|
|
|
|
myHandler.post(() -> itemClick(position, view));
|
|
|
|
threadUI.interrupt();
|
|
|
|
});
|
|
|
|
threadUI.start();
|
|
|
|
});
|
|
|
|
|
|
|
|
// get vehicle menu creation
|
2022-03-16 12:32:28 +00:00
|
|
|
gridVehicle.setOnItemLongClickListener((adapterView, view, i, l) -> {
|
|
|
|
contextMenuPosition = position;
|
|
|
|
iconContextMenu.createMenu(getString(R.string.options)).show();
|
|
|
|
return true;
|
|
|
|
});
|
2022-03-14 09:53:00 +00:00
|
|
|
|
2022-03-16 12:32:28 +00:00
|
|
|
LinearLayout slideLayout = findViewById(R.id.slidelayout);
|
|
|
|
ImageView slideLayoutImageView = findViewById(R.id.slideLayoutImage);
|
|
|
|
LinearLayout linearLayoutVehicles = findViewById(R.id.layoutBig);
|
2022-03-14 09:53:00 +00:00
|
|
|
slideLayout.setOnClickListener(v -> {
|
|
|
|
if (showVehicle) {
|
|
|
|
linearLayoutVehicles.setVisibility(View.GONE);
|
|
|
|
slideLayoutImageView.setImageResource(R.drawable.arrow_right);
|
|
|
|
showVehicle = false;
|
|
|
|
} else {
|
|
|
|
linearLayoutVehicles.setVisibility(View.VISIBLE);
|
|
|
|
slideLayoutImageView.setImageResource(R.drawable.arrow_left);
|
|
|
|
showVehicle = true;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2022-03-16 12:32:28 +00:00
|
|
|
imageViewCheckAll = findViewById(R.id.imageCheckAll);
|
2022-03-14 09:53:00 +00:00
|
|
|
imageViewCheckAll.setSelected(false);
|
|
|
|
imageViewCheckAll.setOnClickListener(arg0 -> {
|
|
|
|
for (int i = 0; i < displayedVehicles.size(); i++)
|
|
|
|
displayedVehicles.set(i, true);
|
|
|
|
|
|
|
|
adapter.changeDisplayAll(!imageViewCheckAll.isSelected());
|
|
|
|
|
|
|
|
|
|
|
|
VehiclesGridViewAdapter.ViewHolder viewLive = (VehiclesGridViewAdapter.ViewHolder) gridVehicle.getChildAt(0).getTag();
|
|
|
|
|
|
|
|
if (!imageViewCheckAll.isSelected())
|
|
|
|
viewLive.imgViewChecked.setImageResource(R.drawable.checked);
|
|
|
|
else
|
|
|
|
viewLive.imgViewChecked.setImageResource(R.drawable.unchecked);
|
|
|
|
|
2022-03-15 13:51:30 +00:00
|
|
|
Enumeration<Long> keyList = getParentTab().getSuperVehHash().keys();
|
2022-03-14 09:53:00 +00:00
|
|
|
while (keyList.hasMoreElements()) {
|
2022-03-16 14:49:04 +00:00
|
|
|
(Objects.requireNonNull(getParentTab().getSuperVehHash().get(keyList.nextElement()))).needUpdate = true;
|
2022-03-14 09:53:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// change button title
|
|
|
|
if (!imageViewCheckAll.isSelected()) {
|
|
|
|
imageViewCheckAll.setSelected(true);
|
|
|
|
imageViewCheckAll.setBackgroundResource(R.drawable.check_all);
|
|
|
|
displayButton.setText(getString(R.string.hideAll));
|
|
|
|
// set all vehicles to be displayed
|
|
|
|
for (int i = 0; i < displayedVehicles.size(); i++)
|
|
|
|
displayedVehicles.set(i, true);
|
|
|
|
} else {
|
|
|
|
imageViewCheckAll.setSelected(false);
|
|
|
|
imageViewCheckAll.setBackgroundResource(R.drawable.uncheck_all);
|
|
|
|
displayButton.setText(getString(R.string.displayAll));
|
|
|
|
// set all vehicles to not be displayed
|
|
|
|
for (int i = 0; i < displayedVehicles.size(); i++)
|
|
|
|
displayedVehicles.set(i, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
// refresh UI
|
|
|
|
displayVehicle(true, LAT_OUTLIMIT, LNG_OUTLIMIT);
|
|
|
|
});
|
|
|
|
|
2022-03-16 12:32:28 +00:00
|
|
|
displayButton = findViewById(R.id.buttonDisplay);
|
2022-03-14 09:53:00 +00:00
|
|
|
displayButton.setText(getString(R.string.displayAll));
|
|
|
|
|
|
|
|
|
|
|
|
displayButton.setOnClickListener(v -> {
|
|
|
|
// set all displayed vehicles to true
|
|
|
|
|
|
|
|
for (int i = 0; i < displayedVehicles.size(); i++)
|
|
|
|
displayedVehicles.set(i, true);
|
|
|
|
|
2022-03-15 13:51:30 +00:00
|
|
|
Enumeration<Long> keyList = getParentTab().getSuperVehHash().keys();
|
2022-03-14 09:53:00 +00:00
|
|
|
while (keyList.hasMoreElements())
|
2022-03-16 14:49:04 +00:00
|
|
|
(Objects.requireNonNull(getParentTab().getSuperVehHash().get(keyList.nextElement()))).needUpdate = true;
|
2022-03-14 09:53:00 +00:00
|
|
|
|
|
|
|
// change button title
|
|
|
|
if (displayButton.getText().toString().equals(getString(R.string.displayAll))) {
|
|
|
|
displayButton.setText(getString(R.string.hideAll));
|
|
|
|
// set all vehicles to be displayed
|
|
|
|
for (int i = 0; i < displayedVehicles.size(); i++)
|
|
|
|
displayedVehicles.set(i, true);
|
|
|
|
} else {
|
|
|
|
displayButton.setText(getString(R.string.displayAll));
|
|
|
|
// set all vehicles to not be displayed
|
|
|
|
for (int i = 0; i < displayedVehicles.size(); i++)
|
|
|
|
displayedVehicles.set(i, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
// refresh UI
|
|
|
|
displayVehicle(true, LAT_OUTLIMIT, LNG_OUTLIMIT);
|
|
|
|
});
|
|
|
|
|
|
|
|
// display Vehicles
|
|
|
|
displayVehicle(true, LAT_OUTLIMIT, LNG_OUTLIMIT);
|
|
|
|
|
|
|
|
// register to receive broadcasts
|
|
|
|
registerBroadcastIntents();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Manipulates the map once available.
|
|
|
|
* This callback is triggered when the map is ready to be used.
|
|
|
|
* This is where we can add markers or lines, add listeners or move the camera. In this case,
|
|
|
|
* we just add a marker near Sydney, Australia.
|
|
|
|
* If Google Play services is not installed on the device, the user will be prompted to install
|
|
|
|
* it inside the SupportMapFragment. This method will only be triggered once the user has
|
|
|
|
* installed Google Play services and returned to the app.
|
|
|
|
*/
|
|
|
|
@Override
|
|
|
|
public void onMapReady(@NonNull GoogleMap googleMap) {
|
|
|
|
this.googleMap = googleMap;
|
2022-03-16 14:49:04 +00:00
|
|
|
GoogleMapsInfoBubble infoBubble = new GoogleMapsInfoBubble(getLayoutInflater(), this, getParentTab().getSuperVehHash());
|
2022-03-16 08:54:41 +00:00
|
|
|
this.googleMap.setInfoWindowAdapter(infoBubble);
|
2022-03-14 09:53:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onBackPressed() {
|
|
|
|
// cancel loading dialog if showing
|
|
|
|
if (loadingDialog.isShowing()) {
|
|
|
|
cancelLoadingDialog();
|
|
|
|
} else {
|
|
|
|
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
|
|
|
builder.setMessage(getString(R.string.exit))
|
|
|
|
.setCancelable(false)
|
|
|
|
.setNeutralButton(getString(R.string.logout), (dialog, id) -> getParentTab().whenBackPressed(AppParams.ActivityResult.logout))
|
|
|
|
.setPositiveButton(getString(R.string.ext), (dialog, id) -> getParentTab().whenBackPressed(AppParams.ActivityResult.exit))
|
|
|
|
.setNegativeButton(getString(R.string.cancel), (dialog, id) -> dialog.cancel());
|
|
|
|
AlertDialog alert = builder.create();
|
|
|
|
alert.show();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onStart() {
|
|
|
|
super.onStart();
|
|
|
|
if (isFirstRun) {
|
|
|
|
// show loading dialog
|
|
|
|
showLoadingDialog("Getting vehicles from database...");
|
|
|
|
// send liveActivity
|
|
|
|
getParentTab().setLiveActivity((AbstractLiveActivity) activity);
|
|
|
|
// get all vehicles
|
|
|
|
isAck = false;
|
|
|
|
// start a thread to wait 3 seconds for ack
|
|
|
|
new Thread(() -> {
|
|
|
|
try {
|
|
|
|
Thread.sleep(3000);
|
|
|
|
} catch (InterruptedException e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
SM.Exception(e.toString());
|
|
|
|
// Restore interrupted state
|
|
|
|
Thread.currentThread().interrupt();
|
|
|
|
}
|
|
|
|
// if not getVehicle not isAck
|
|
|
|
if (!isAck)
|
|
|
|
myHandler.post(cancelLoadingDialogRUN);
|
|
|
|
}).start();
|
|
|
|
|
|
|
|
SM.Debug("GetVehs");
|
|
|
|
isFirstRun = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onPause() {
|
|
|
|
super.onPause();
|
|
|
|
SM.Debug("onPause");
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onResume() {
|
|
|
|
super.onResume();
|
|
|
|
|
|
|
|
// clear previous vehicles
|
|
|
|
SM.Debug("onResume");
|
|
|
|
displayVehicle(true, LAT_OUTLIMIT, LNG_OUTLIMIT);
|
|
|
|
}
|
|
|
|
|
|
|
|
final Runnable cancelLoadingDialogRUN = LiveActivity.this::cancelLoadingDialog;
|
|
|
|
|
|
|
|
// cancel loading dialog and show sending error message
|
|
|
|
private void cancelLoadingDialog() {
|
|
|
|
// cancel loading dialog
|
|
|
|
try {
|
|
|
|
loadingDialog.cancel();
|
|
|
|
} catch (Exception ex) {
|
|
|
|
SM.Exception(ex.toString());
|
|
|
|
}
|
|
|
|
if (!isAck) {
|
|
|
|
// show connection error
|
|
|
|
Toast.makeText(context, "Could not get Vehicles... ", Toast.LENGTH_SHORT).show();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void createIconContextMenu() {
|
|
|
|
iconContextMenu = new IconContextMenu(this, 1);
|
|
|
|
iconContextMenu.addItem(res, R.string.enable, R.drawable.enable, MENU_ENABLE);
|
|
|
|
iconContextMenu.addItem(res, R.string.disable, R.drawable.disable, MENU_DISABLE);
|
|
|
|
iconContextMenu.addItem(res, R.string.poll, R.drawable.poll, MENU_POLL);
|
|
|
|
|
|
|
|
//set onclick listener for context menu
|
|
|
|
iconContextMenu.setOnClickListener(menuId -> {
|
|
|
|
int radioCode = 30;
|
|
|
|
switch (menuId) {
|
|
|
|
case MENU_ENABLE: {
|
|
|
|
// send change to AppServer
|
|
|
|
optionForUnit(radioCode, MENU_ENABLE, liveVehicle.get(contextMenuPosition).id + "");
|
|
|
|
if (AppParams.DEMO)
|
|
|
|
vehicleStatusReceived(liveVehicle.get(contextMenuPosition).id, 101, 1);
|
|
|
|
SM.Debug("MENU: Enable for " + liveVehicle.get(contextMenuPosition).id);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case MENU_DISABLE: {
|
|
|
|
// send change to AppServer
|
|
|
|
optionForUnit(radioCode, MENU_DISABLE, liveVehicle.get(contextMenuPosition).id + "");
|
|
|
|
if (AppParams.DEMO)
|
|
|
|
vehicleStatusReceived(liveVehicle.get(contextMenuPosition).id, 101, 0);
|
|
|
|
SM.Debug("MENU: Disable for " + liveVehicle.get(contextMenuPosition).id);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case MENU_REMOTE: {
|
|
|
|
// send change to AppServer
|
|
|
|
optionForUnit(radioCode, MENU_REMOTE, liveVehicle.get(contextMenuPosition).id + "");
|
|
|
|
SM.Debug("MENU: Remote for " + liveVehicle.get(contextMenuPosition).id);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case MENU_POLL: {
|
|
|
|
// send change to AppServer
|
|
|
|
optionForUnit(radioCode, MENU_POLL, liveVehicle.get(contextMenuPosition).id + "");
|
|
|
|
if (AppParams.DEMO) {
|
2022-03-15 13:51:30 +00:00
|
|
|
getParentTab().setImei(liveVehicle.get(contextMenuPosition).sc_id + "");
|
2022-03-14 09:53:00 +00:00
|
|
|
getParentTab().updateDemoPosition();
|
|
|
|
getParentTab().updateResultsPollInUi("realpha");
|
|
|
|
}
|
|
|
|
|
|
|
|
SM.Debug("MENU: P for " + liveVehicle.get(contextMenuPosition).id);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
throw new IllegalStateException("Unexpected value: " + menuId);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
public void displayVehicle(boolean withZoom, double latZoom, double lngZoom) {
|
2022-03-15 12:45:18 +00:00
|
|
|
if (googleMap != null) {
|
2022-03-16 12:41:05 +00:00
|
|
|
String openWindow = "";
|
|
|
|
for (Marker marker : markers) {
|
|
|
|
if (marker.isInfoWindowShown()) {
|
|
|
|
openWindow = marker.getTitle();
|
|
|
|
}
|
|
|
|
}
|
2022-03-15 12:45:18 +00:00
|
|
|
googleMap.clear();
|
|
|
|
|
|
|
|
for (int i = 0; i < displayedVehicles.size(); i++) {
|
|
|
|
if (displayedVehicles.get(i)) {
|
2022-03-16 14:49:04 +00:00
|
|
|
SuperVehicle tmpSuper = getParentTab().getSuperVehHash().get(Long.valueOf(liveVehicle.get(i).imei));
|
2022-03-15 12:45:18 +00:00
|
|
|
|
|
|
|
if (tmpSuper != null) {
|
|
|
|
LatLng newLocation = new LatLng(tmpSuper.lat, tmpSuper.lng);
|
2022-03-16 08:54:41 +00:00
|
|
|
MarkerOptions markerOptions = new MarkerOptions().position(newLocation).title(liveVehicle.get(i).imei);
|
2022-03-15 12:45:18 +00:00
|
|
|
|
|
|
|
BitmapDescriptor markerIcon = getProperBitmap(tmpSuper.getLargeIcon(), tmpSuper.name);
|
|
|
|
markerOptions.icon(markerIcon);
|
|
|
|
|
2022-03-16 12:41:05 +00:00
|
|
|
Marker marker = this.googleMap.addMarker(markerOptions);
|
|
|
|
if (openWindow.equals(marker.getTitle()))
|
|
|
|
marker.showInfoWindow();
|
|
|
|
|
|
|
|
markers.add(marker);
|
2022-03-15 12:45:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-03-14 09:53:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public void showOpenedBalloon(boolean demo) {
|
|
|
|
//TODO: add show balloon
|
|
|
|
}
|
|
|
|
|
2022-03-15 12:45:18 +00:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2022-03-14 09:53:00 +00:00
|
|
|
public void showLoadingDialog(String message) {
|
|
|
|
loadingDialog = new Dialog(context);
|
|
|
|
loadingDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
|
|
|
|
loadingDialog.setContentView(R.layout.dialogloading);
|
|
|
|
loadingDialog.setCancelable(true);
|
|
|
|
loadingDialog.setCanceledOnTouchOutside(false);
|
|
|
|
|
2022-03-16 12:32:28 +00:00
|
|
|
Button cancel = loadingDialog.findViewById(R.id.buttonCancel);
|
2022-03-14 09:53:00 +00:00
|
|
|
cancel.setVisibility(View.GONE);
|
2022-03-16 12:32:28 +00:00
|
|
|
TextView textView1 = loadingDialog.findViewById(R.id.textView1);
|
2022-03-14 09:53:00 +00:00
|
|
|
textView1.setText(message);
|
|
|
|
|
|
|
|
loadingDialog.show();
|
|
|
|
}
|
|
|
|
|
|
|
|
// save Vehicles
|
|
|
|
@Override
|
|
|
|
public void vehiclesReceived(ArrayList<Vehicle> list) {
|
|
|
|
|
|
|
|
SM.Debug("vehiclesReceived");
|
|
|
|
isAck = true;
|
|
|
|
liveVehicle = list;
|
|
|
|
disabledVehicles = new ArrayList<>();
|
|
|
|
displayedVehicles = new ArrayList<>();
|
|
|
|
// set displayed to false and add icons to hashTable
|
|
|
|
int i = 0;
|
|
|
|
SM.Debug("DISPLAY LIVE VEHICLE");
|
|
|
|
for (Vehicle veh : list) {
|
|
|
|
|
|
|
|
SM.Debug(veh.toString());
|
|
|
|
liveVehicle.get(i).id = veh.sc_id;
|
|
|
|
i++;
|
|
|
|
// set vehicle to false
|
|
|
|
displayedVehicles.add(AppParams.DEMO && (veh.sc_id == 101 || veh.sc_id == 102));
|
|
|
|
// set disable to false
|
|
|
|
disabledVehicles.add(!veh.status);
|
|
|
|
|
|
|
|
// add vehicle to hash Table according to driver_id
|
2022-03-16 12:32:28 +00:00
|
|
|
if (tableHashOverlay.get((int) veh.driver_id) == null) {
|
2022-03-14 09:53:00 +00:00
|
|
|
ArrayList<SuperVehicle> 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);
|
|
|
|
tableHashOverlay.put((int) veh.driver_id, array);
|
|
|
|
} else {
|
|
|
|
// another vehicle with same driver_id exists
|
|
|
|
ArrayList<SuperVehicle> array = tableHashOverlay.get((int) veh.driver_id);
|
|
|
|
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);
|
|
|
|
// add vehicle to array
|
|
|
|
if (array != null) {
|
|
|
|
array.add(superVehicle);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// set adapter
|
|
|
|
adapter = new VehiclesGridViewAdapter(activity, context, list, disabledVehicles);
|
|
|
|
adapter.notifyDataSetChanged();
|
|
|
|
|
|
|
|
// Update UI
|
|
|
|
myHandler.post(updateResultsRUN);
|
|
|
|
|
|
|
|
// hide loading dialog
|
|
|
|
loadingDialog.cancel();
|
|
|
|
if (!AppParams.DEMO)
|
|
|
|
getLastPos();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create runnable for posting
|
|
|
|
final Runnable updateResultsRUN = this::updateResultsUI;
|
|
|
|
|
|
|
|
// show vehicles in gridView
|
|
|
|
private void updateResultsUI() {
|
|
|
|
gridVehicle.setAdapter(adapter);
|
|
|
|
try {
|
|
|
|
// hide loading dialog
|
|
|
|
loadingDialog.cancel();
|
|
|
|
} catch (Exception e) {
|
|
|
|
SM.Exception(e.toString());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void refreshMap() {
|
|
|
|
// Update UI
|
|
|
|
myHandler.post(updateMapResults);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void pollReceived(int position, double lat, double lng) {
|
|
|
|
// Update UI
|
|
|
|
latPoll = lat;
|
|
|
|
lngPoll = lng;
|
|
|
|
this.position = position;
|
|
|
|
myHandler.post(updatePollResults);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void vehicleStatusReceived(long imei, int opCode, int status) {
|
|
|
|
vehStatus = status;
|
|
|
|
SM.Debug("UpdateOptions from APP with-> imei: " + imei + " | opCode: " + opCode + " | status: " + vehStatus);
|
|
|
|
contextMenuPosition = getPositionFromImei(imei);
|
|
|
|
// Update UI
|
|
|
|
myHandler.post(updateOptionsRUN);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void emergencyAlarmReceived(int position, double lat, double lng) {
|
|
|
|
pollReceived(position,lat,lng);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void updatePosition(int pos) {
|
|
|
|
contextMenuPosition = pos;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create runnable for posting
|
|
|
|
final Runnable updateMapResults = () -> displayVehicle(false, LAT_OUTLIMIT, LNG_OUTLIMIT);
|
|
|
|
|
|
|
|
// Create runnable for posting
|
|
|
|
final Runnable updatePollResults = () -> {
|
|
|
|
if (position != -1) {
|
|
|
|
SM.Debug("updatePosition :" + position + " last value:" + displayedVehicles.get(position));
|
|
|
|
// change in adapter
|
|
|
|
adapter.changeDisplayed(position, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
displayVehicle(true, latPoll, lngPoll); };
|
|
|
|
|
|
|
|
// Create runnable for posting
|
|
|
|
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));
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* visual modifications when a vehicle is clicked
|
|
|
|
*
|
|
|
|
* @param position position in grid that was clicked
|
|
|
|
* @param view View in which will do the modifications
|
|
|
|
*/
|
|
|
|
private void itemClick(int position, View view) {
|
|
|
|
// change displayed state
|
|
|
|
displayedVehicles.set(position, !Boolean.TRUE.equals(displayedVehicles.get(position)));
|
|
|
|
|
|
|
|
// change in the adapter
|
|
|
|
adapter.changeDisplayed(position, displayedVehicles.get(position));
|
|
|
|
|
|
|
|
// change check image for selected value
|
|
|
|
VehiclesGridViewAdapter.ViewHolder viewLive = (VehiclesGridViewAdapter.ViewHolder) view.getTag();
|
|
|
|
|
|
|
|
if (Boolean.TRUE.equals(displayedVehicles.get(position)))
|
|
|
|
viewLive.imgViewChecked.setImageResource(R.drawable.checked);
|
|
|
|
else
|
|
|
|
viewLive.imgViewChecked.setImageResource(R.drawable.unchecked);
|
|
|
|
|
|
|
|
// check if all values are identical
|
|
|
|
boolean identical = true;
|
|
|
|
for (Boolean displ : displayedVehicles)
|
|
|
|
if (!Objects.equals(displ, displayedVehicles.get(0))) {
|
|
|
|
identical = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// change image when all values are identical
|
|
|
|
if (identical && Boolean.TRUE.equals(displayedVehicles.get(0))) {
|
|
|
|
imageViewCheckAll.setSelected(true);
|
|
|
|
imageViewCheckAll.setBackgroundResource(R.drawable.check_all);
|
|
|
|
} else if (identical && Boolean.TRUE.equals(!displayedVehicles.get(0))) {
|
|
|
|
imageViewCheckAll.setSelected(false);
|
|
|
|
imageViewCheckAll.setBackgroundResource(R.drawable.uncheck_all);
|
|
|
|
}
|
|
|
|
|
|
|
|
// display vehicle
|
|
|
|
displayVehicle(true, LAT_OUTLIMIT, LNG_OUTLIMIT);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* get last position for all vehicles
|
|
|
|
*/
|
|
|
|
private void getLastPos() {
|
|
|
|
getParentTab().executeNetworkStuff(new String[]{OperationCodes.GetLastPositions + "", AppParams.USERID + ""});
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* send a command that enable/disable a vehicle or request a poll
|
|
|
|
*
|
|
|
|
* @param radioCode is a hardcoded values set to 30
|
|
|
|
* @param opCode the operation code. It can be :
|
|
|
|
* MENU_ENABLE = 150,
|
|
|
|
* MENU_DISABLE = 151,
|
|
|
|
* MENU_REMOTE = 161,
|
|
|
|
* MENU_POLL = 154;
|
|
|
|
* @param scId vehicle imei for which we do the operation
|
|
|
|
*/
|
|
|
|
public void optionForUnit(int radioCode, int opCode, String scId) {
|
|
|
|
// last values is set to 0 for disable and 1 for others
|
|
|
|
getParentTab().executeNetworkStuff(new String[]{OperationCodes.Option4Unit + "", radioCode + "", (opCode == MENU_DISABLE ? MENU_ENABLE : opCode) + "", scId,
|
|
|
|
(opCode == MENU_DISABLE ? 0 : 1) + ""});
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* return the position in the grid for a Vehicle specified by imei
|
|
|
|
*
|
|
|
|
* @param imei vehicle's imei
|
|
|
|
*/
|
|
|
|
private int getPositionFromImei(long imei) {
|
|
|
|
int positionFromImei = -1;
|
|
|
|
for (int i = 0; i < liveVehicle.size(); i++)
|
|
|
|
if (liveVehicle.get(i).imei.equalsIgnoreCase(imei + ""))
|
|
|
|
positionFromImei = i;
|
|
|
|
SM.Debug("Position: " + positionFromImei);
|
|
|
|
return positionFromImei;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Register for broadcasts
|
|
|
|
*/
|
|
|
|
private void registerBroadcastIntents() {
|
|
|
|
// zone and channel change intent
|
|
|
|
IntentFilter intentFilter = new IntentFilter(OperationCodes.UNIT_STATUS_UPDATE + "");
|
|
|
|
this.registerReceiver(mReceiver, intentFilter);
|
|
|
|
}
|
|
|
|
|
|
|
|
//The BroadcastReceiver that listens for Notification broadcasts
|
|
|
|
public final BroadcastReceiver mReceiver = new BroadcastReceiver() {
|
|
|
|
@Override
|
|
|
|
public void onReceive(Context context, Intent intent) {
|
|
|
|
|
|
|
|
final String action = intent.getAction();
|
|
|
|
|
|
|
|
if (action.equals(OperationCodes.UNIT_STATUS_UPDATE + "")) {
|
|
|
|
try {
|
|
|
|
final String[] extra = intent.getStringExtra("unitStatus").split("#");
|
|
|
|
|
|
|
|
SM.Debug("extra has " + extra.length + " objects");
|
|
|
|
Toast.makeText(context, "Unit was " + (Integer.parseInt(extra[1]) == 0 ? "DISABLED" : "ENABLED"), Toast.LENGTH_LONG).show();
|
|
|
|
|
|
|
|
myHandler.post(() -> {
|
|
|
|
vehStatus = Integer.parseInt(extra[1]);
|
|
|
|
contextMenuPosition = getPositionFromImei(Integer.parseInt(extra[0]));
|
|
|
|
disabledVehicles.remove(contextMenuPosition);
|
|
|
|
// invert logic is used
|
|
|
|
disabledVehicles.add(contextMenuPosition, vehStatus != 1);
|
|
|
|
adapter.changeDisabled(contextMenuPosition, disabledVehicles.get(contextMenuPosition));
|
|
|
|
});
|
|
|
|
} catch (Exception ex) {
|
|
|
|
SM.Exception("Exception in live BroadCastReceived" + ex.toString());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
2022-03-17 08:18:23 +00:00
|
|
|
|
|
|
|
@Override
|
|
|
|
public GoogleMap getMap() {
|
|
|
|
return googleMap;
|
|
|
|
}
|
2022-03-14 09:53:00 +00:00
|
|
|
}
|