Merge branch 'PR-master-auto-online' of s416084/find-my-tutor-android into master

This commit is contained in:
Mieszko Wrzeszczyński 2018-12-06 22:38:02 +00:00 committed by Gogs
commit 26e12d68f3
17 changed files with 224 additions and 131 deletions

View File

@ -29,7 +29,7 @@
</value> </value>
</option> </option>
</component> </component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK"> <component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8 (1)" 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

@ -10,7 +10,7 @@ android {
applicationId "com.uam.wmi.findmytutor" applicationId "com.uam.wmi.findmytutor"
minSdkVersion 22 minSdkVersion 22
targetSdkVersion 27 targetSdkVersion 27
versionCode 14 versionCode 15
versionName "0.9.1-alpha" versionName "0.9.1-alpha"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true vectorDrawables.useSupportLibrary = true
@ -28,8 +28,14 @@ repositories {
url 'http://dl.bintray.com/amulyakhare/maven' url 'http://dl.bintray.com/amulyakhare/maven'
} }
} }
def acraVersion = '5.2.1'
dependencies { dependencies {
implementation "ch.acra:acra-http:$acraVersion"
implementation "ch.acra:acra-toast:$acraVersion"
implementation "ch.acra:acra-notification:$acraVersion"
implementation fileTree(include: ['*.jar'], dir: 'libs') implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'com.android.support:preference-v7:27.1.1' implementation 'com.android.support:preference-v7:27.1.1'
implementation 'com.android.support:appcompat-v7:27.1.1' implementation 'com.android.support:appcompat-v7:27.1.1'

View File

@ -17,6 +17,7 @@
<uses-feature android:name="android.hardware.location.gps" /> <uses-feature android:name="android.hardware.location.gps" />
<application <application
android:name=".FindMyTutor"
android:allowBackup="true" android:allowBackup="true"
android:icon="@mipmap/ic_launcher" android:icon="@mipmap/ic_launcher"
android:label="@string/app_name" android:label="@string/app_name"
@ -53,7 +54,7 @@
<activity <activity
android:name=".activity.TutorTab" android:name=".activity.TutorTab"
android:theme="@style/AppTheme"></activity> android:theme="@style/AppTheme"/>
</application> </application>
</manifest> </manifest>

View File

@ -0,0 +1,75 @@
package com.uam.wmi.findmytutor;
import android.app.Application;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import static org.acra.ReportField.*;
import org.acra.ACRA;
import org.acra.annotation.AcraNotification;
import org.acra.config.CoreConfigurationBuilder;
import org.acra.config.HttpSenderConfigurationBuilder;
import org.acra.config.ToastConfigurationBuilder;
import org.acra.data.StringFormat;
import org.acra.sender.HttpSender;
import java.util.HashMap;
import java.util.Map;
@AcraNotification(resText = R.string.notification_text,
resTitle = R.string.notification_title,
resChannelName = R.string.notification_channel)
public class FindMyTutor extends Application {
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
// ACRA core
CoreConfigurationBuilder builder = new CoreConfigurationBuilder(this)
.setBuildConfigClass(BuildConfig.class)
.setReportContent(REPORT_ID, PHONE_MODEL, LOGCAT, USER_APP_START_DATE, USER_CRASH_DATE, SHARED_PREFERENCES,
ANDROID_VERSION, STACK_TRACE, CUSTOM_DATA, BUILD_CONFIG)
.setReportFormat(StringFormat.JSON);
// Toast for user
builder.setBuildConfigClass(BuildConfig.class)
.setReportFormat(StringFormat.JSON);
builder.getPluginConfigurationBuilder(
ToastConfigurationBuilder.class
).setResText(R.string.acra_toast_text);
SharedPreferences sharedPreferences = base.getSharedPreferences("com.uam.wmi.findmytutor_preferences", Context.MODE_PRIVATE);
Map header = new HashMap();
String token = sharedPreferences.getString("API_KEY", "KEY_EMPTY");
header.put("Authorization","Bearer " + token);
// Api POST
builder.getPluginConfigurationBuilder(
HttpSenderConfigurationBuilder.class
// ).setUri("http://192.168.0.15:3000/api/acra")
).setUri("https://s416084.projektstudencki.pl/develop/api/Feedback/autoFeedback")
.setHttpMethod(HttpSender.Method.POST)
.setHttpHeaders(header)
.setEnabled(true);
ACRA.init(this, builder);
//Shared preferences
ACRA.getErrorReporter().putCustomData("USER_ID", sharedPreferences.getString("USER_ID", "no user id"));
}
// Called by the system when the device configuration changes while your component is running.
// Overriding this method is totally optional!
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
}
// This is called when the overall system is running low on memory,
// and would like actively running processes to tighten their belts.
// Overriding this method is totally optional!
@Override
public void onLowMemory() {
super.onLowMemory();
}
}

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;

View File

@ -49,10 +49,10 @@ 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.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;
@ -80,8 +80,6 @@ public class MapActivity extends BaseActivity
private int mInterval = 10000; private int mInterval = 10000;
private Handler mHandler = new Handler(); private Handler mHandler = new Handler();
private Runnable mStatusChecker; private Runnable mStatusChecker;
private Handler manualLocHandler = new Handler();
private Runnable manualLocStatusChecker;
private MapView mapView; private MapView mapView;
private MapboxMap mapboxMap; private MapboxMap mapboxMap;
private Button selectLocationButton; private Button selectLocationButton;
@ -100,6 +98,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) {
@ -115,7 +114,9 @@ public class MapActivity extends BaseActivity
mStatusChecker = () -> { mStatusChecker = () -> {
try { try {
fetchTopCoords(); if (shouldFetchNewCoords) {
fetchTopCoords();
}
} finally { } finally {
mHandler.postDelayed(mStatusChecker, mInterval); mHandler.postDelayed(mStatusChecker, mInterval);
} }
@ -226,7 +227,7 @@ public class MapActivity extends BaseActivity
private void showError(Throwable e) { private void showError(Throwable e) {
String message; String message;
Log.e("ERR",e.toString()); Log.e("ERR", e.toString());
if (e instanceof HttpException) { if (e instanceof HttpException) {
ResponseBody responseBody = ((HttpException) e).response().errorBody(); ResponseBody responseBody = ((HttpException) e).response().errorBody();
@ -343,7 +344,6 @@ public class MapActivity extends BaseActivity
}); });
}); });
alertDialog.show(); alertDialog.show();
} }
@ -372,7 +372,7 @@ public class MapActivity extends BaseActivity
private void SaveCurrentManualLocation(PredefinedCoordViewModel resp) { private void SaveCurrentManualLocation(PredefinedCoordViewModel resp) {
Toast.makeText(getApplicationContext(), R.string.location_saved, Toast.LENGTH_SHORT).show(); Toast.makeText(getApplicationContext(), R.string.location_saved, Toast.LENGTH_SHORT).show();
PrefUtils.putCurrentManualLocation(getApplicationContext(),resp.getPredefinedCoordinateId()); PrefUtils.putCurrentManualLocation(getApplicationContext(), resp.getPredefinedCoordinateId());
} }
private void fetchTopCoords() { private void fetchTopCoords() {
@ -389,7 +389,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();
} }
@ -439,7 +439,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(),
@ -592,6 +592,7 @@ public class MapActivity extends BaseActivity
public void onResume() { public void onResume() {
super.onResume(); super.onResume();
mapView.onResume(); mapView.onResume();
shouldFetchNewCoords = true;
} }
@Override @Override
@ -604,12 +605,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
@ -623,8 +626,6 @@ public class MapActivity extends BaseActivity
super.onDestroy(); super.onDestroy();
mapView.onDestroy(); mapView.onDestroy();
mHandler.removeCallbacks(mStatusChecker); mHandler.removeCallbacks(mStatusChecker);
// TODO remove after BG sending
manualLocHandler.removeCallbacks(manualLocStatusChecker);
disposable.dispose(); disposable.dispose();
} }
@ -723,6 +724,6 @@ public class MapActivity extends BaseActivity
} }
public void adjustMapToSearch(Integer zoom) { public void adjustMapToSearch(Integer zoom) {
MapUtils.setZoom(mapboxMap,zoom); MapUtils.setZoom(mapboxMap, zoom);
} }
} }

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

@ -23,26 +23,27 @@ import retrofit2.converter.gson.GsonConverterFactory;
public class ApiClient { public class ApiClient {
private static Retrofit retrofit = null; private static Retrofit retrofit = null;
private static int REQUEST_TIMEOUT = 60; private static int REQUEST_TIMEOUT = 60;
private static OkHttpClient okHttpClient; private static OkHttpClient okHttpClient;
private static final String BASE_URL = "https://s416084.projektstudencki.pl/master/"; private static final String BASE_URL = "https://s416084.projektstudencki.pl/master/";
public static Retrofit getClient(Context context) { public static Retrofit getClient(Context context) {
if (okHttpClient == null) if (okHttpClient == null)
initOkHttp(context); initOkHttp(context);
if (retrofit == null) { if (retrofit == null) {
retrofit = new Retrofit.Builder() retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL) .baseUrl(BASE_URL)
.client(okHttpClient) .client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create()) .addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build(); .build();
}
return retrofit;
} }
return retrofit;
}
private static void initOkHttp(final Context context) { private static void initOkHttp(final Context context) {

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

@ -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

@ -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

@ -159,9 +159,14 @@
<string name="network_error">Błąd sieci!</string> <string name="network_error">Błąd sieci!</string>
<string name="manual_status_error">Błąd podczas pobierania danych.</string> <string name="manual_status_error">Błąd podczas pobierania danych.</string>
<string name="error_status_fetch">Błąd podczas pobierania statusów.</string> <string name="error_status_fetch">Błąd podczas pobierania statusów.</string>
<string name="notification_text">Upss. Coś poszło nie tak. Pracujemy nad tym!</string>
<string name="lack_duty_hours">Brak informacji o dyzurze.</string> <string name="lack_duty_hours">Brak informacji o dyzurze.</string>
<string name="lack_note">Brak notatki.</string> <string name="lack_note">Brak notatki.</string>
<string name="search">Wyszukiwarka</string> <string name="search">Wyszukiwarka</string>
<string name="description_notdisturb">Nie przeszkadzać</string>
<string name="description_awaiting">Czekam na studentów</string>
<string name="description_onholidays">Na wakacjach</string>
<string name="title_description">Status</string>
</resources> </resources>

View File

@ -73,11 +73,16 @@
<string name="key_location_level">key_location_level</string> <string name="key_location_level">key_location_level</string>
<string name="status_list_title">Choose status</string> <string name="status_list_title">Choose status</string>
<string name="key_status_value">key_status_value</string> <string name="key_status_value" translatable="false">key_status_value</string>
<string name="status_switch_title">Status</string> <string name="status_switch_title">Status</string>
<string name="description_busy">Busy</string> <string name="description_busy">Busy</string>
<string name="description_available">Available</string> <string name="description_available">Available</string>
<string name="description_consultation">Consultation</string> <string name="description_consultation">Consultation</string>
<string name="description_notdisturb">Do not disturb</string>
<string name="description_awaiting">Waiting for students</string>
<string name="description_onholidays">On holidays</string>
<string name="title_description">Status</string>
<string name="title_manual_status">Add custom status</string> <string name="title_manual_status">Add custom status</string>
@ -228,7 +233,13 @@
<string name="network_error">Network Error!</string> <string name="network_error">Network Error!</string>
<string name="manual_status_error">Error handling status fetch</string> <string name="manual_status_error">Error handling status fetch</string>
<string name="error_status_fetch">Error handling status fetch</string> <string name="error_status_fetch">Error handling status fetch</string>
<string name="acra_toast_text" translatable="false">Sorry, the application crashed. A report will be sent to the developers</string>
<string name="notification_text">Sorry, the application crashed. A report will be sent to the developers</string>
<string name="notification_title" translatable="false">FMT Crash</string>
<string name="notification_channel" translatable="false">FMT</string>
<string name="lack_duty_hours">Lack information about duty hours</string> <string name="lack_duty_hours">Lack information about duty hours</string>
<string name="lack_note">No note.</string> <string name="lack_note">No note.</string>
<string name="search">Search</string> <string name="search">Search</string>
<string name="mockup_location_string" translatable="false">mock location string</string>
</resources> </resources>