This commit is contained in:
Domagalski 2018-12-10 18:25:22 +01:00
commit b0927c174a
18 changed files with 239 additions and 123 deletions

View File

@ -1,10 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="CMakeSettings">
<configurations>
<configuration PROFILE_NAME="Debug" CONFIG_NAME="Debug" />
</configurations>
</component>
<component name="NullableNotNullManager"> <component name="NullableNotNullManager">
<option name="myDefaultNullable" value="android.support.annotation.Nullable" /> <option name="myDefaultNullable" value="android.support.annotation.Nullable" />
<option name="myDefaultNotNull" value="android.support.annotation.NonNull" /> <option name="myDefaultNotNull" value="android.support.annotation.NonNull" />
@ -34,7 +29,7 @@
</value> </value>
</option> </option>
</component> </component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8 (1)" project-jdk-type="JavaSDK"> <component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" /> <output url="file://$PROJECT_DIR$/build/classes" />
</component> </component>
<component name="ProjectType"> <component name="ProjectType">

View File

@ -20,19 +20,16 @@ import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity; import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.SearchView; import android.support.v7.widget.SearchView;
import android.support.v7.widget.Toolbar; import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import android.widget.Toast; import android.widget.Toast;
import com.mapbox.mapboxsdk.Mapbox;
import com.uam.wmi.findmytutor.R; import com.uam.wmi.findmytutor.R;
import com.uam.wmi.findmytutor.service.BackgroundLocalizationService; import com.uam.wmi.findmytutor.service.BackgroundLocalizationService;
import com.uam.wmi.findmytutor.utils.ActiveFragment; import com.uam.wmi.findmytutor.utils.ActiveFragment;
import com.uam.wmi.findmytutor.utils.FeedbackUtils; import com.uam.wmi.findmytutor.utils.FeedbackUtils;
import com.uam.wmi.findmytutor.utils.MapUtils;
import com.uam.wmi.findmytutor.utils.PrefUtils; import com.uam.wmi.findmytutor.utils.PrefUtils;
import com.uam.wmi.findmytutor.utils.RxSearchObservable; import com.uam.wmi.findmytutor.utils.RxSearchObservable;
@ -49,8 +46,8 @@ import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers; import io.reactivex.schedulers.Schedulers;
import static com.uam.wmi.findmytutor.utils.Consts.deafultMapZoom; import static com.uam.wmi.findmytutor.utils.Const.defaultMapZoom;
import static com.uam.wmi.findmytutor.utils.Consts.searchMapZoom; import static com.uam.wmi.findmytutor.utils.Const.searchMapZoom;
import static com.uam.wmi.findmytutor.utils.PrefUtils.storeBackgroundLocationStatus; import static com.uam.wmi.findmytutor.utils.PrefUtils.storeBackgroundLocationStatus;
@ -77,6 +74,7 @@ public abstract class BaseActivity
private Fragment userListFragment; private Fragment userListFragment;
private ActiveFragment activeFragment = ActiveFragment.NONE; private ActiveFragment activeFragment = ActiveFragment.NONE;
private Fragment activeBottomMenu = null;
private SearchView searchView; private SearchView searchView;
@SuppressLint("CheckResult") @SuppressLint("CheckResult")
@ -275,7 +273,7 @@ public abstract class BaseActivity
searchView.setOnQueryTextFocusChangeListener((v, hasFocus) -> { searchView.setOnQueryTextFocusChangeListener((v, hasFocus) -> {
if (!hasFocus && activeFragment.equals(ActiveFragment.NONE)) { if (!hasFocus && activeFragment.equals(ActiveFragment.NONE)) {
restoreMapMarkers(); restoreMapMarkers();
adjustMapToSearch(deafultMapZoom); adjustMapToSearch(defaultMapZoom);
} }
if(hasFocus && activeFragment.equals(ActiveFragment.NONE)){ if(hasFocus && activeFragment.equals(ActiveFragment.NONE)){
@ -351,7 +349,7 @@ public abstract class BaseActivity
} else if (itemId == R.id.nav_user_list) { } else if (itemId == R.id.nav_user_list) {
loadUserListFragment(); loadUserListFragment();
} }
selectBottomNavigationBarItem(itemId);
}, 300); }, 300);
return true; return true;
@ -363,6 +361,7 @@ public abstract class BaseActivity
FragmentTransaction ft = getFragmentManager().beginTransaction(); FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.activity_content, sharingFragment); ft.replace(R.id.activity_content, sharingFragment);
ft.commit(); ft.commit();
} }
private void loadUserListFragment() { private void loadUserListFragment() {
@ -372,8 +371,8 @@ public abstract class BaseActivity
FragmentTransaction ft = getFragmentManager().beginTransaction(); FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.activity_content, userListFragment); ft.replace(R.id.activity_content, userListFragment);
ft.commit(); ft.commit();
}
}
private void updateNavigationBarState() { private void updateNavigationBarState() {
int actionId = getNavigationMenuItemId(); int actionId = getNavigationMenuItemId();
@ -385,9 +384,6 @@ public abstract class BaseActivity
item.setChecked(true); item.setChecked(true);
} }
abstract int getNavigationMenuItemId(); abstract int getNavigationMenuItemId();
abstract int getContentViewId(); abstract int getContentViewId();
} }

View File

@ -21,7 +21,6 @@ import com.auth0.android.jwt.JWT;
import com.jakewharton.retrofit2.adapter.rxjava2.HttpException; import com.jakewharton.retrofit2.adapter.rxjava2.HttpException;
import com.uam.wmi.findmytutor.R; import com.uam.wmi.findmytutor.R;
import com.uam.wmi.findmytutor.model.JwtToken; import com.uam.wmi.findmytutor.model.JwtToken;
import com.uam.wmi.findmytutor.model.LdapUser;
import com.uam.wmi.findmytutor.model.User; import com.uam.wmi.findmytutor.model.User;
import com.uam.wmi.findmytutor.model.ValidateUser; import com.uam.wmi.findmytutor.model.ValidateUser;
import com.uam.wmi.findmytutor.network.ApiClient; import com.uam.wmi.findmytutor.network.ApiClient;
@ -149,11 +148,8 @@ public class LoginActivity extends AppCompatActivity {
private void loginProcess(String email, String password) { private void loginProcess(String email, String password) {
ValidateUser user = new ValidateUser(email, password); ValidateUser user = new ValidateUser(email, password);
LdapUser fuser = new LdapUser(email, password, "wmi", "tutor", "henryk", "zdzblo", email);
// disposable.add(ldapService.validate(user)
disposable.add(ldapService.fakeValidate(fuser)
disposable.add(ldapService.validate(user)
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe(this::handleResponse, this::handleError)); .subscribe(this::handleResponse, this::handleError));

View File

@ -52,12 +52,13 @@ import com.uam.wmi.findmytutor.service.CoordinateService;
import com.uam.wmi.findmytutor.service.PredefinedStatusesService; import com.uam.wmi.findmytutor.service.PredefinedStatusesService;
import com.uam.wmi.findmytutor.service.UserService; import com.uam.wmi.findmytutor.service.UserService;
import com.uam.wmi.findmytutor.utils.ApproximatedLocalization; import com.uam.wmi.findmytutor.utils.ApproximatedLocalization;
import com.uam.wmi.findmytutor.utils.InfoHelperUtils;
import com.uam.wmi.findmytutor.utils.ManualLocationUtils; import com.uam.wmi.findmytutor.utils.ManualLocationUtils;
import com.uam.wmi.findmytutor.utils.MapMarker; import com.uam.wmi.findmytutor.utils.MapMarker;
import com.uam.wmi.findmytutor.utils.MapUtils;
import com.uam.wmi.findmytutor.utils.PrefUtils; import com.uam.wmi.findmytutor.utils.PrefUtils;
import com.uam.wmi.findmytutor.utils.RestApiHelper; import com.uam.wmi.findmytutor.utils.RestApiHelper;
import com.uam.wmi.findmytutor.utils.SharingLevel; import com.uam.wmi.findmytutor.utils.SharingLevel;
import com.uam.wmi.findmytutor.utils.MapUtils;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
@ -72,6 +73,8 @@ import io.reactivex.schedulers.Schedulers;
import okhttp3.ResponseBody; import okhttp3.ResponseBody;
import timber.log.Timber; import timber.log.Timber;
import static com.mapbox.mapboxsdk.Mapbox.getApplicationContext;
public class MapActivity extends BaseActivity public class MapActivity extends BaseActivity
implements PermissionsListener, OnMapReadyCallback { implements PermissionsListener, OnMapReadyCallback {
@ -103,6 +106,7 @@ public class MapActivity extends BaseActivity
private String myId; private String myId;
private boolean isTutor; private boolean isTutor;
private ApproximatedLocalization approximatedLocalization; private ApproximatedLocalization approximatedLocalization;
private boolean shouldFetchNewCoords = true;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
@ -118,7 +122,9 @@ public class MapActivity extends BaseActivity
mStatusChecker = () -> { mStatusChecker = () -> {
try { try {
fetchTopCoords(); if (shouldFetchNewCoords) {
fetchTopCoords();
}
} finally { } finally {
mHandler.postDelayed(mStatusChecker, mInterval); mHandler.postDelayed(mStatusChecker, mInterval);
} }
@ -348,7 +354,6 @@ public class MapActivity extends BaseActivity
}); });
}); });
alertDialog.show(); alertDialog.show();
} }
@ -394,7 +399,7 @@ public class MapActivity extends BaseActivity
public void onSuccess(List<Coordinate> coordsList) { public void onSuccess(List<Coordinate> coordsList) {
if (tmpLocalMarker != null && coordsList.isEmpty()) { if (tmpLocalMarker != null && coordsList.isEmpty()) {
Timber.e("200 empty []"); Log.e("MapActivity", "200 empty []");
mapboxMap.clear(); mapboxMap.clear();
} }
@ -444,7 +449,7 @@ public class MapActivity extends BaseActivity
} }
LatLng toDestination = new LatLng(element.getLatitude(), element.getLongitude()); LatLng toDestination = new LatLng(element.getLatitude(), element.getLongitude());
// TODO fix flickiering markers
ValueAnimator markerAnimator = ObjectAnimator.ofObject(marker, "position", ValueAnimator markerAnimator = ObjectAnimator.ofObject(marker, "position",
new MapUtils.LatLngEvaluator(), new MapUtils.LatLngEvaluator(),
marker.getPosition(), marker.getPosition(),
@ -597,6 +602,7 @@ public class MapActivity extends BaseActivity
public void onResume() { public void onResume() {
super.onResume(); super.onResume();
mapView.onResume(); mapView.onResume();
shouldFetchNewCoords = true;
} }
@Override @Override
@ -609,12 +615,14 @@ public class MapActivity extends BaseActivity
protected void onStop() { protected void onStop() {
super.onStop(); super.onStop();
mapView.onStop(); mapView.onStop();
shouldFetchNewCoords = false;
} }
@Override @Override
public void onPause() { public void onPause() {
super.onPause(); super.onPause();
mapView.onPause(); mapView.onPause();
shouldFetchNewCoords = false;
} }
@Override @Override
@ -745,4 +753,6 @@ public class MapActivity extends BaseActivity
popupWindow.showAtLocation(anchorView, Gravity.NO_GRAVITY, popupWindow.showAtLocation(anchorView, Gravity.NO_GRAVITY,
location[0] + anchorView.getWidth(), location[1] + anchorView.getHeight()); location[0] + anchorView.getWidth(), location[1] + anchorView.getHeight());
} }
} }

View File

@ -15,6 +15,7 @@ import android.view.ViewGroup;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.ListView; import android.widget.ListView;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast;
import com.annimon.stream.Stream; import com.annimon.stream.Stream;
import com.jakewharton.retrofit2.adapter.rxjava2.HttpException; import com.jakewharton.retrofit2.adapter.rxjava2.HttpException;
@ -27,6 +28,7 @@ import com.uam.wmi.findmytutor.model.User;
import com.uam.wmi.findmytutor.network.ApiClient; import com.uam.wmi.findmytutor.network.ApiClient;
import com.uam.wmi.findmytutor.service.TutorTabApi; import com.uam.wmi.findmytutor.service.TutorTabApi;
import com.uam.wmi.findmytutor.service.UserService; import com.uam.wmi.findmytutor.service.UserService;
import com.uam.wmi.findmytutor.utils.InfoHelperUtils;
import com.uam.wmi.findmytutor.utils.MyDividerItemDecoration; import com.uam.wmi.findmytutor.utils.MyDividerItemDecoration;
import com.uam.wmi.findmytutor.utils.RecyclerTouchListener; import com.uam.wmi.findmytutor.utils.RecyclerTouchListener;
import com.uam.wmi.findmytutor.utils.RestApiHelper; import com.uam.wmi.findmytutor.utils.RestApiHelper;
@ -76,12 +78,19 @@ public class UsersListFragment extends Fragment {
mAdapter = new TutorsListAdapter(getActivity().getApplicationContext(), tutorsFiltered); mAdapter = new TutorsListAdapter(getActivity().getApplicationContext(), tutorsFiltered);
View view = inflater.inflate(R.layout.users_list, container, false); View view = inflater.inflate(R.layout.users_list, container, false);
view.setBackgroundColor(getResources().getColor(android.R.color.white)); view.setBackgroundColor(getResources().getColor(android.R.color.white));
return view; return view;
} }
public void onViewCreated(View view, Bundle savedInstanceState) { public void onViewCreated(View view, Bundle savedInstanceState) {
ButterKnife.bind(this, view); ButterKnife.bind(this, view);
// TODO: Merge with code from home
InfoHelperUtils infoHelperUtils = new InfoHelperUtils();
view.findViewById(R.id.userListInfoImageButton).setOnClickListener(v ->
infoHelperUtils.infoDialogUserList(getActivity(), v)
);
userService = ApiClient.getClient(getApplicationContext()) userService = ApiClient.getClient(getApplicationContext())
.create(UserService.class); .create(UserService.class);
@ -151,11 +160,11 @@ public class UsersListFragment extends Fragment {
List<String> dutyHoursList = Stream.of(tutorTabViewModel.getDutyHours()) List<String> dutyHoursList = Stream.of(tutorTabViewModel.getDutyHours())
.map(DutyHourViewModel::getSummary).toList(); .map(DutyHourViewModel::getSummary).toList();
if(dutyHoursList.isEmpty()){ if (dutyHoursList.isEmpty()) {
dutyHoursList.add(getString(R.string.lack_duty_hours)); dutyHoursList.add(getString(R.string.lack_duty_hours));
} }
if(tutorTabViewModel.getNote().isEmpty()){ if (tutorTabViewModel.getNote().isEmpty()) {
userNoteText = getString(R.string.lack_note); userNoteText = getString(R.string.lack_note);
} }
@ -225,7 +234,7 @@ public class UsersListFragment extends Fragment {
private int sortByUserName(User t1, User t2) { private int sortByUserName(User t1, User t2) {
return plCollator.compare(t1.getLastName(),t2.getLastName()); return plCollator.compare(t1.getLastName(), t2.getLastName());
} }
private void showError(Throwable e) { private void showError(Throwable e) {
@ -234,7 +243,7 @@ public class UsersListFragment extends Fragment {
if (e instanceof HttpException) { if (e instanceof HttpException) {
ResponseBody responseBody = ((HttpException) e).response().errorBody(); ResponseBody responseBody = ((HttpException) e).response().errorBody();
message = RestApiHelper.getErrorMessage(responseBody); message = RestApiHelper.getErrorMessage(responseBody);
}else{ } else {
message = "Network Error !"; message = "Network Error !";
} }

View File

@ -3,7 +3,9 @@ package com.uam.wmi.findmytutor.model;
import android.util.Range; import android.util.Range;
import com.google.gson.annotations.SerializedName; import com.google.gson.annotations.SerializedName;
import com.uam.wmi.findmytutor.utils.Const;
import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.UUID; import java.util.UUID;
@ -14,8 +16,9 @@ import io.swagger.annotations.ApiModelProperty;
*/ */
public class Coordinate extends BaseResponse { public class Coordinate extends BaseResponse {
Range<Double> latitudeRange = Range.create(52.46598, 52.467545); private Range<Double> latitudeRange = Const.latitudeRange;
Range<Double> longtitudeRange = Range.create(16.926099, 16.927794); private Range<Double> longtitudeRange = Const.longitudeRange;
private List<String> allowedApproximatedLocations = Const.validApproximatedLocations;
@SerializedName("coordinateId") @SerializedName("coordinateId")
private UUID coordinateId = null; private UUID coordinateId = null;
@ -47,7 +50,7 @@ public class Coordinate extends BaseResponse {
public Coordinate (Double latitude, Double longitude, Double altitude, String approximatedLocation, String label, String userId, String displayMode) { public Coordinate (Double latitude, Double longitude, Double altitude, String approximatedLocation, String label, String userId, String displayMode) {
if (!latitudeRange.contains(latitude)) throw new IllegalArgumentException("Inappropriate latitude value" + latitude); if (!latitudeRange.contains(latitude)) throw new IllegalArgumentException("Inappropriate latitude value" + latitude);
if (!longtitudeRange.contains(longitude)) throw new IllegalArgumentException("Inappropriate longitude value" + longitude); if (!longtitudeRange.contains(longitude)) throw new IllegalArgumentException("Inappropriate longitude value" + longitude);
//if (approximatedLocation == null) throw new IllegalArgumentException("Inappropriate approximatedLocation"); if (!allowedApproximatedLocations.contains(approximatedLocation)) throw new IllegalArgumentException("Inappropriate approximatedLocation");
this.latitude = latitude; this.latitude = latitude;
this.longitude = longitude; this.longitude = longitude;

View File

@ -16,13 +16,13 @@ import android.os.AsyncTask;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder; import android.os.IBinder;
import android.support.annotation.RequiresApi; import android.support.annotation.RequiresApi;
import android.support.v4.app.ActivityCompat; import android.support.v4.app.ActivityCompat;
import android.support.v4.app.NotificationCompat; import android.support.v4.app.NotificationCompat;
import android.util.Log; import android.util.Log;
import com.annimon.stream.Stream;
import com.google.android.gms.location.FusedLocationProviderClient; import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationServices; import com.google.android.gms.location.LocationServices;
import com.jakewharton.retrofit2.adapter.rxjava2.HttpException; import com.jakewharton.retrofit2.adapter.rxjava2.HttpException;
@ -31,25 +31,28 @@ import com.mapbox.mapboxsdk.geometry.LatLng;
import com.uam.wmi.findmytutor.model.Coordinate; import com.uam.wmi.findmytutor.model.Coordinate;
import com.uam.wmi.findmytutor.network.ApiClient; import com.uam.wmi.findmytutor.network.ApiClient;
import com.uam.wmi.findmytutor.utils.ApproximatedLocalization; import com.uam.wmi.findmytutor.utils.ApproximatedLocalization;
import com.uam.wmi.findmytutor.utils.MapUtils;
import com.uam.wmi.findmytutor.utils.PrefUtils; import com.uam.wmi.findmytutor.utils.PrefUtils;
import com.uam.wmi.findmytutor.utils.RestApiHelper; import com.uam.wmi.findmytutor.utils.RestApiHelper;
import com.uam.wmi.findmytutor.utils.SharingLevel; import com.uam.wmi.findmytutor.utils.SharingLevel;
import com.uam.wmi.findmytutor.utils.MapUtils;
import org.apache.commons.collections4.queue.CircularFifoQueue;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.TimerTask; import java.util.TimerTask;
import java.util.concurrent.atomic.AtomicReference;
import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable; import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.observers.DisposableSingleObserver; import io.reactivex.observers.DisposableSingleObserver;
import io.reactivex.schedulers.Schedulers; import io.reactivex.schedulers.Schedulers;
import okhttp3.ResponseBody; import okhttp3.ResponseBody;
import timber.log.Timber;
import static com.uam.wmi.findmytutor.utils.Consts.presenceApproximatedName; import static com.uam.wmi.findmytutor.utils.Const.defaultBackgroundLocationInterval;
import static com.uam.wmi.findmytutor.utils.Consts.presenceLatitude; import static com.uam.wmi.findmytutor.utils.Const.presenceApproximatedName;
import static com.uam.wmi.findmytutor.utils.Consts.presenceLongitude; import static com.uam.wmi.findmytutor.utils.Const.presenceLatitude;
import static com.uam.wmi.findmytutor.utils.Const.presenceLongitude;
import static com.uam.wmi.findmytutor.utils.PrefUtils.storeBackgroundLocationStatus; import static com.uam.wmi.findmytutor.utils.PrefUtils.storeBackgroundLocationStatus;
public class BackgroundLocalizationService extends Service { public class BackgroundLocalizationService extends Service {
@ -57,21 +60,20 @@ public class BackgroundLocalizationService extends Service {
private static final String TAG = "MyLocationService"; private static final String TAG = "MyLocationService";
private static final int LOCATION_INTERVAL = 1000; private static final int LOCATION_INTERVAL = 1000;
private static final float LOCATION_DISTANCE = 5f; private static final float LOCATION_DISTANCE = 5f;
public static String str_receiver = "background.location.broadcast"; private static long notify_interval = defaultBackgroundLocationInterval;
private static long notify_interval = 10000; private static long notify_interval_inside_building = defaultBackgroundLocationInterval;
Location mLastLocation; private static long notify_interval_outside_building = 360000;
Boolean stopService = false; private static int coordinatesHistoryLength = 10;
Intent intent; private Location mLastLocation;
ArrayList<String> providers = new ArrayList<String>(); private Boolean stopService = false;
LocationListener[] mLocationListeners; private ArrayList<String> providers = new ArrayList<String>();
private LocationListener[] mLocationListeners;
private CircularFifoQueue<Location> coordinatesHistory = new CircularFifoQueue<Location>(coordinatesHistoryLength);
private LocationManager mLocationManager = null; private LocationManager mLocationManager = null;
private Handler mHandler = new Handler(); private Handler mHandler = new Handler();
private HandlerThread mHandlerThread = null;
private Runnable mStatusChecker; private Runnable mStatusChecker;
private FusedLocationProviderClient mFusedLocationClient; private FusedLocationProviderClient mFusedLocationClient;
public BackgroundLocalizationService() { public BackgroundLocalizationService() {
providers.add(LocationManager.GPS_PROVIDER); providers.add(LocationManager.GPS_PROVIDER);
providers.add(LocationManager.NETWORK_PROVIDER); providers.add(LocationManager.NETWORK_PROVIDER);
@ -82,7 +84,6 @@ public class BackgroundLocalizationService extends Service {
new LocationListener(LocationManager.NETWORK_PROVIDER), new LocationListener(LocationManager.NETWORK_PROVIDER),
new LocationListener(LocationManager.PASSIVE_PROVIDER) new LocationListener(LocationManager.PASSIVE_PROVIDER)
}; };
} }
@Override @Override
@ -146,27 +147,39 @@ public class BackgroundLocalizationService extends Service {
} }
if (!stopService) { if (!stopService) {
mStatusChecker = () -> { mStatusChecker = () -> {
try { try {
fn_getlocation(); fn_getlocation();
changeBackgroundMode();
} finally { } finally {
mHandler.postDelayed(mStatusChecker, notify_interval); mHandler.postDelayed(mStatusChecker, notify_interval);
} }
}; };
AsyncTask.execute(mStatusChecker); AsyncTask.execute(mStatusChecker);
} }
}
private void changeBackgroundMode() {
if (coordinatesHistory.size() > 4) {
Boolean shouldExtendTimeInterval = Stream.of(coordinatesHistory)
.map(MapUtils::checkIfCoordinateIsValid).takeWhile(s -> !s).toList().size() == coordinatesHistory.size();
Boolean shouldAbbreviateTimeInterval = Stream.of(coordinatesHistory).
map(MapUtils::checkIfCoordinateIsValid).toList().get(coordinatesHistory.size() - 1);
if (shouldExtendTimeInterval) {
notify_interval = notify_interval_outside_building;
} else if (shouldAbbreviateTimeInterval) {
notify_interval = notify_interval_inside_building;
}
}
} }
@RequiresApi(api = Build.VERSION_CODES.O) @RequiresApi(api = Build.VERSION_CODES.O)
private void startMyOwnForeground() { private void startMyOwnForeground() {
String NOTIFICATION_CHANNEL_ID = "com.example.simpleapp"; String NOTIFICATION_CHANNEL_ID = "com.example.fmt";
String channelName = "My Background Service"; String channelName = "My Background Service";
NotificationChannel chan = new NotificationChannel(NOTIFICATION_CHANNEL_ID, channelName, NotificationManager.IMPORTANCE_NONE); NotificationChannel chan = new NotificationChannel(NOTIFICATION_CHANNEL_ID, channelName, NotificationManager.IMPORTANCE_NONE);
chan.setLightColor(Color.BLUE); chan.setLightColor(Color.BLUE);
@ -198,29 +211,35 @@ public class BackgroundLocalizationService extends Service {
List<String> providers1 = mLocationManager.getProviders(true); List<String> providers1 = mLocationManager.getProviders(true);
Location bestLocation = null; Location bestLocation = null;
AtomicReference<Boolean> triggerAnotherLocationListener = new AtomicReference<>(false);
for (String provider : providers1) {
Location location = mLocationManager.getLastKnownLocation(provider);
if (location == null) {
continue;
}
if (bestLocation == null || location.getAccuracy() < bestLocation.getAccuracy()) {
bestLocation = location;
}
}
Log.e("Best localization:", String.valueOf(bestLocation));
mFusedLocationClient.getLastLocation().addOnSuccessListener( mFusedLocationClient.getLastLocation().addOnSuccessListener(
location -> { location -> {
if (location != null) { if (location != null) {
mLastLocation = location; mLastLocation = location;
coordinatesHistory.add(location);
fn_update(location); fn_update(location);
} }
triggerAnotherLocationListener.set(true);
}); });
if (triggerAnotherLocationListener.get()) {
for (String provider : providers1) {
Location location = mLocationManager.getLastKnownLocation(provider);
if (location == null) {
continue;
}
if (bestLocation == null || location.getAccuracy() < bestLocation.getAccuracy()) {
bestLocation = location;
}
}
coordinatesHistory.add(bestLocation);
Log.e("Best localization:", String.valueOf(bestLocation));
}
} }
private void fn_update(Location location) { private void fn_update(Location location) {
@ -241,7 +260,6 @@ public class BackgroundLocalizationService extends Service {
return; return;
} }
mLocationManager.removeUpdates(listener); mLocationManager.removeUpdates(listener);
Log.i(TAG, "Removed");
} catch (Exception ex) { } catch (Exception ex) {
Log.i(TAG, "fail to remove location listener, ignore", ex); Log.i(TAG, "fail to remove location listener, ignore", ex);
@ -258,13 +276,6 @@ public class BackgroundLocalizationService extends Service {
} }
} }
private class TimerTaskToGetLocation extends TimerTask {
@Override
public void run() {
mHandler.post(BackgroundLocalizationService.this::fn_getlocation);
}
}
private class LocationListener implements android.location.LocationListener { private class LocationListener implements android.location.LocationListener {
public LocationListener(String provider) { public LocationListener(String provider) {
@ -344,9 +355,6 @@ public class BackgroundLocalizationService extends Service {
locationLevel locationLevel
); );
Log.e(TAG, String.valueOf(coordinate));
disposable.add( disposable.add(
coordinateService coordinateService
.postCoordinate(coordinate) .postCoordinate(coordinate)
@ -362,17 +370,11 @@ public class BackgroundLocalizationService extends Service {
@SuppressLint("LongLogTag") @SuppressLint("LongLogTag")
@Override @Override
public void onError(Throwable e) { public void onError(Throwable e) {
Log.e("CoordinateService onError", e.getMessage()); Log.e("CoordinateService onError", e.getMessage());
if (e instanceof HttpException) {
ResponseBody responseBody = ((HttpException) e).response().errorBody();
Log.e("CoordinateService onError", RestApiHelper.getErrorMessage(responseBody));
}
} }
})); }));
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
Log.e(TAG,e.toString()); Log.e(TAG, e.toString());
} }
return null; return null;

View File

@ -10,7 +10,7 @@ import retrofit2.http.POST;
public interface FeedbackService { public interface FeedbackService {
@POST("api/Feedback") @POST("api/Feedback")
Observable<Void> postFeedback(@Body Feedback feedback); Observable<Response<Void>> postFeedback(@Body Feedback feedback);
@GET("api/Feedback") @GET("api/Feedback")
Observable<Void> getFeedback(); Observable<Void> getFeedback();

View File

@ -48,7 +48,7 @@ public class ApproximatedLocalization {
return Objects.requireNonNull(Objects.requireNonNull(feature.getStringProperty("name"))); return Objects.requireNonNull(Objects.requireNonNull(feature.getStringProperty("name")));
} }
return null; return Const.presenceApproximatedName;
} }
public List<Double> getMiddlePointOfBuildingPart(String buildingPart) { public List<Double> getMiddlePointOfBuildingPart(String buildingPart) {

View File

@ -0,0 +1,18 @@
package com.uam.wmi.findmytutor.utils;
import android.util.Range;
import java.util.Arrays;
import java.util.List;
public class Const {
public final static Integer defaultBackgroundLocationInterval = 15000;
public final static Integer defaultMapZoom = 17;
public final static Integer searchMapZoom = 13;
public final static Double presenceLatitude = 52.466365;
public final static Double presenceLongitude = 16.926792;
public final static String presenceApproximatedName = "Unknown";
public final static Range<Double> latitudeRange = Range.create(52.466092, 52.467529);
public final static Range<Double> longitudeRange = Range.create(16.926159, 16.927759);
public final static List<String> validApproximatedLocations = Arrays.asList("Skrzydło B", "Skrzydło A", "Aule", "Łącznik", "Biblioteka", "Hol", "Unknown");
}

View File

@ -1,13 +0,0 @@
package com.uam.wmi.findmytutor.utils;
import android.util.Range;
public class Consts {
public final static Integer deafultMapZoom = 17;
public final static Integer searchMapZoom = 13;
public final static Double presenceLatitude = 52.466365;
public final static Double presenceLongitude = 16.926792;
public final static String presenceApproximatedName = "Unknown";
public final static Range<Double> latitudeRange = Range.create(52.466709, 52.467007);
public final static Range<Double> longtitudeRange = Range.create(16.926159, 16.926976);
}

View File

@ -82,10 +82,9 @@ public class FeedbackUtils {
try { try {
appVersion = activityContext.getPackageManager().getPackageInfo(activityContext.getPackageName(), 0).versionName; appVersion = activityContext.getPackageManager().getPackageInfo(activityContext.getPackageName(), 0).versionName;
if( !mode ){ if( !mode ){
body = PrefUtils.getUserFirstName(activityContext) + " " + PrefUtils.getUserLastName(activityContext) + "\n" + body;
userFeedback = new Feedback(mode, userFeedback = new Feedback(mode,
header, header,
PrefUtils.getUserId(activityContext), PrefUtils.getUserFirstName(activityContext) + " " + PrefUtils.getUserLastName(activityContext) + " | " + PrefUtils.getUserId(activityContext),
"Android "+ Build.VERSION.RELEASE, "Android "+ Build.VERSION.RELEASE,
appVersion, appVersion,
Build.MODEL, Build.MODEL,
@ -113,8 +112,10 @@ public class FeedbackUtils {
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe(this::handleResponse, this::handleError)); .subscribe(this::handleResponse, this::handleError));
} }
private void handleResponse( Void resp) { private void handleResponse( Response<Void> resp) {
Toast.makeText(activityContext, activityContext.getString(R.string.modal_feedback_thankyou), Toast.LENGTH_SHORT).show(); Toast.makeText(activityContext, activityContext.getString(R.string.modal_feedback_thankyou), Toast.LENGTH_SHORT).show();
Log.d("FEEDBACK toast","gdzie jest mój tost");
} }
private void handleError(Throwable error) { private void handleError(Throwable error) {

View File

@ -0,0 +1,28 @@
package com.uam.wmi.findmytutor.utils;
import android.app.Activity;
import android.content.Context;
import android.support.v7.app.AlertDialog;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.PopupWindow;
import android.widget.Toast;
import com.uam.wmi.findmytutor.R;
import static com.mapbox.mapboxsdk.Mapbox.getApplicationContext;
public class InfoHelperUtils {
public static void infoDialogUserList(Activity activity, View anchorView ) {
View popupView = LayoutInflater.from(activity).inflate(R.layout.feedback_modal, null);
final PopupWindow popupWindow = new PopupWindow(popupView, WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT);
popupWindow.showAsDropDown(popupView);
Toast.makeText(getApplicationContext(), anchorView.getId() + "", Toast.LENGTH_SHORT).show();
}
}

View File

@ -44,8 +44,6 @@ public class ManualLocationUtils {
activityContext = context; activityContext = context;
} }
private void handleError(Throwable error) { private void handleError(Throwable error) {
if (error instanceof HttpException) { if (error instanceof HttpException) {

View File

@ -2,30 +2,20 @@ package com.uam.wmi.findmytutor.utils;
import android.animation.TypeEvaluator; import android.animation.TypeEvaluator;
import android.content.Context; import android.content.Context;
import android.graphics.Color;
import android.location.Location; import android.location.Location;
import android.view.Gravity;
import android.view.View;
import android.widget.FrameLayout;
import android.content.res.AssetManager;
import com.mapbox.mapboxsdk.annotations.Polygon;
import com.mapbox.mapboxsdk.annotations.PolygonOptions;
import com.mapbox.mapboxsdk.camera.CameraPosition; import com.mapbox.mapboxsdk.camera.CameraPosition;
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory; import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
import com.mapbox.mapboxsdk.geometry.LatLng; import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.geometry.LatLngBounds; import com.mapbox.mapboxsdk.geometry.LatLngBounds;
import com.mapbox.mapboxsdk.maps.MapView; import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap; import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.style.layers.FillLayer;
import com.mapbox.mapboxsdk.style.layers.Layer;
import com.uam.wmi.findmytutor.model.Coordinate;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import static com.uam.wmi.findmytutor.utils.Consts.latitudeRange; import static com.uam.wmi.findmytutor.utils.Const.latitudeRange;
import static com.uam.wmi.findmytutor.utils.Consts.longtitudeRange; import static com.uam.wmi.findmytutor.utils.Const.longitudeRange;
public class MapUtils { public class MapUtils {
@ -85,7 +75,7 @@ public class MapUtils {
} }
public static Boolean checkIfCoordinateIsValid(Location coordinate){ public static Boolean checkIfCoordinateIsValid(Location coordinate){
return (!latitudeRange.contains(coordinate.getLatitude()) && !longtitudeRange.contains(coordinate.getLongitude())); return latitudeRange.contains(coordinate.getLatitude()) && longitudeRange.contains(coordinate.getLongitude());
} }
// Function for marker animation // Function for marker animation

View File

@ -1,15 +1,22 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
xmlns:mapbox="http://schemas.android.com/apk/res-auto"
android:id="@+id/coordinator_layout" android:id="@+id/coordinator_layout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:fontFamily="@font/lato_regular" android:fontFamily="@font/lato_regular"
tools:context=".activity.UsersListFragment"> tools:context=".activity.UsersListFragment">
<include layout="@layout/users_list_main" /> <include layout="@layout/users_list_main" />
<ImageButton
android:id="@+id/userListInfoImageButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
mapbox:srcCompat="@drawable/outline_info_24"/>
</android.support.design.widget.CoordinatorLayout> </android.support.design.widget.CoordinatorLayout>

View File

@ -175,6 +175,44 @@
<string name="map_info_text_marker_exact">lokalizacja dokładna (udostępniana z GPS telefonu)</string> <string name="map_info_text_marker_exact">lokalizacja dokładna (udostępniana z GPS telefonu)</string>
<string name="map_info_text_marker_approximated">lokalizacja przybliżona</string> <string name="map_info_text_marker_approximated">lokalizacja przybliżona</string>
<string name="map_info_text_marker_manual"> lokalizacja manualna (wybrana ręcznie)</string> <string name="map_info_text_marker_manual"> lokalizacja manualna (wybrana ręcznie)</string>
<!--(PL) Map Activity info helper-->
<string name="map_info_text">Na mapie wyświetlane są markery reprezentujące profesorów udostępniających w tej chwili swoją lokalizację.</string>
<!--(PL) Blacklist info helper-->
<string name="info_icon_blacklist_p1">W tym panelu możesz dodać użytkowników do swojej czarnej listy. Użytkownicy z czarnej listy nie będą widzieć żadnych danych które udostępniasz - lokalizacji, twojego statusu online, czy informacji o obecności.</string>
<string name="info_icon_blacklist_p2">Jedyną informacją która wciąż będzie udostępniana wszystkim jest notka w Twoim profilu.</string>
<string name="info_icon_blacklist_p3">Za pomocą powyższego przycisku możesz włączyć lub wyłączyć używanie czarnej listy. Czarna lista nie może być aktywna jednocześnie z białą listą.</string>
<!--(PL) Whitelist info helper-->
<string name="info_icon_whitelist_p1">W tym panelu możesz dodać użytkowników do swojej białej listy. Użytkownicy SPOZA listy nie będą widzieć żadnych danych które udostępniasz - lokalizacji, twojego statusu online, czy informacji o obecności.</string>
<string name="info_icon_whitelist_p2">Jedyną informacją która wciąż będzie udostępniana wszystkim jest notka w Twoim profilu.</string>
<string name="info_icon_whitelist_p3">Za pomocą powyższego przycisku możesz włączyć lub wyłączyć używanie białej listy. Biała lista nie może być aktywna jednocześnie z czarną listą.</string>
<!--(PL) Tutor tab info helper-->
<string name="info_icon_tutor_tab_p1">W tej zakładce możesz edytować swój profil widoczny dla wszystkich użytkowników.</string>
<string name="info_icon_tutor_tab_p2">Jeśli zakładka jest pusta lub zawiera nieaktualne dane, możesz je ręcznie uaktualnić.</string>
<string name="info_icon_tutor_tab_p3">W każdej chwili możesz przywrócić dane ze strony WMI za pomocą przycisku (jeśli są dostępne na stronie).</string>
<string name="info_icon_tutor_tab_p4">Dodatkowo możesz uzupełnić notkę, aby przekazać jakąś informację widoczną dla wszystkich studentów: np. “dzisiejszy dyżur odwołany” itp.</string>
<!--(PL) Sharing Tab info helper-->
<string name="info_icon_sharing_tab_p1">W tej zakładce możesz włączyć/wyłączyć udostępnianie swojej lokalizacji oraz ją skonfigurować.</string>
<string name="info_icon_sharing_tab_p2">Niektóre zmiany mogą nie być widoczne od razu! Odświeżanie informacji zajmuje do 2 minut.</string>
<string name="info_icon_sharing_tab_p3">Udostępniać możesz na jednym z 4 poziomów:</string>
<string name="info_icon_sharing_tab_p3_level_exact">- dokładny - lokalizacja wyświetlana na mapie na podstawie GPS</string>
<string name="info_icon_sharing_tab_p3_level_approximate">- przybliżony - przybliżona lokalizacja wyświetlana na podstawie GPS</string>
<string name="info_icon_sharing_tab_p3_level_manual">- manualny - udostępnianie z ręcznie wybranego punktu na mapie</string>
<string name="info_icon_sharing_tab_p3_level_presence">- tylko obecność - udostępnianie jedynie informacji o pojawieniu się na wydziale (aktywny na liście), bez udostępniania lokalizacji</string>
<string name="info_icon_sharing_tab_p4">Każdy poziom z wyjątkiem manualnie wybranej lokalizacji automatycznie zaczyna udostępniać po wejściu na wydział i przestaje udostępniać po jego opuszczeniu. Wystarczy włączyć udostępnianie, a lokalizacja nie będzie udostępniana tylko przy obecności na wydziale.</string>
<string name="info_icon_sharing_tab_p5">Udostępnianie w dowolnym momencie można wyłączyć za pomocą przełącznika.</string>
<string name="info_icon_sharing_tab_p6">Dodatkowo, do Twojej lokalizacji możesz dodać status opisowy (będzie on widoczny dla użytkowników po kliknięciu w marker).</string>
<string name="info_icon_sharing_tab_p7">Zarówno manualne lokalizacje jak i statusy możesz dodać do listy, które potem możesz wybrać w wygodny sposób.</string>
<!--(PL) Userlist Tab info helper-->
<string name="info_icon_userlist_tab_p1">W tym panelu znajduje się listę profesorów. Ich status symbolizowany jest przez kolorowe kropki:</string>
<string name="info_icon_userlist_tab_level_status_online"> GREEN dot - użytkownik jest obecnie online</string>
<string name="info_icon_userlist_tab_level_status_offline">RED dot - użytkownik jest obecnie offline</string>
<string name="info_icon_userlist_tab_level_status_inactive">BLACK dot - użytkownik jest nieaktywny (nie udostępnił żadnych danych o lokalizacji od conajmniej tygodnia).</string>
</resources> </resources>

View File

@ -251,4 +251,42 @@
<string name="map_info_text_marker_manual">manual localization (manually picked)</string> <string name="map_info_text_marker_manual">manual localization (manually picked)</string>
<!--(ENG) Map Activity info helper-->
<string name="map_info_text">There are markers on the map which represent tutors sharing their location at the very moment.</string>
<!--(ENG) Blacklist info helper-->
<string name="info_icon_blacklist_p1">In this panel you can add users to your blacklist. Users from the blacklist cant see any data that you share - localization, online status, or information about presence.</string>
<string name="info_icon_blacklist_p2">The only thing which remains public is the note in your profile.</string>
<string name="info_icon_blacklist_p3">With the switch you can turn on/off usage of the blacklist. Blacklist and whitelist cannot be active at the same time.</string>
<!--(ENG) Whitelist info helper-->
<string name="info_icon_whitelist_p1">In this panel you can add users to your whitelist. Users OUT OF the whitelist cant see any data that you share - localization, online status, or information about presence.</string>
<string name="info_icon_whitelist_p2">The only thing which remains public is the note in your profile.</string>
<string name="info_icon_whitelist_p3">With the switch you can turn on/off usage of the whitelist. Blacklist and whitelist cannot be active at the same time.</string>
<!--(ENG) Tutor Tab info helper-->
<string name="info_icon_tutor_tab_p1">In this tab you can edit you profile visible for all the users.</string>
<string name="info_icon_tutor_tab_p2">If the tab is empty or contains outdated information, you can update them manually.</string>
<string name="info_icon_tutor_tab_p3">Any time you can restore data from the WMI website with the button (if the data is available).</string>
<string name="info_icon_tutor_tab_p4">Additionally, you can fill your note, to share a message visible for all the users: for example “todays duty hours are cancelled” etc.</string>
<!--(ENG) Sharing Tab info helper-->
<string name="info_icon_sharing_tab_p1">In this tab you can turn on/off sharing your localization and configure it.</string>
<string name="info_icon_sharing_tab_p2">Some of the changes may not happen immediately! Refreshing information takes up to 2 minutes.</string>
<string name="info_icon_sharing_tab_p3">You can share your localization on one of the 4 levels:</string>
<string name="info_icon_sharing_tab_p3_level_exact">- exact - localization displayed on a map, based on GPS</string>
<string name="info_icon_sharing_tab_p3_level_approximate">- approximated - approximated localization based on GPS</string>
<string name="info_icon_sharing_tab_p3_level_manual">- manual - sharing from manually picked point</string>
<string name="info_icon_sharing_tab_p3_level_presence">- presence only - sharing only information whether you are present on the faculty or not, without sharing your localization</string>
<string name="info_icon_sharing_tab_p4">Each level, except from manual, will be automatically turned on when entering, and turn off when leaving the faculty. You only need to make sure that sharing is on, and the localization will be shared only when on the faculty.</string>
<string name="info_icon_sharing_tab_p5">Sharing can be turned off at any time with the switch.</string>
<string name="info_icon_sharing_tab_p6">Additionally, you can add descriptive status to your localization (visible for users after clicking on a marker).</string>
<string name="info_icon_sharing_tab_p7">Both manual localizations and statuses can be added to a list, and then used them in a convenient way. </string>
<!--(ENG) Userlist tab info helper-->
<string name="info_icon_userlist_tab_p1">This panel contains the list of tutors. Their status is represented by colorful dots:</string>
<string name="info_icon_userlist_tab_level_status_online">GREEN dot - user is currently online</string>
<string name="info_icon_userlist_tab_level_status_offline">RED dot - user is currently offline</string>
<string name="info_icon_userlist_tab_level_status_inactive">BLACK dot - user is inactive (didnt share any localization data since 7 days)</string>
</resources> </resources>