2016-08-29 12:50:41 +00:00
|
|
|
/**
|
|
|
|
* MainActivity.java
|
|
|
|
* Implements the app's main activity
|
2017-11-28 21:02:45 +00:00
|
|
|
* The main activity sets up the main view
|
2016-08-29 12:50:41 +00:00
|
|
|
*
|
|
|
|
* This file is part of
|
|
|
|
* TRACKBOOK - Movement Recorder for Android
|
|
|
|
*
|
2018-01-12 16:42:47 +00:00
|
|
|
* Copyright (c) 2016-18 - Y20K.org
|
2016-08-29 12:50:41 +00:00
|
|
|
* Licensed under the MIT-License
|
|
|
|
* http://opensource.org/licenses/MIT
|
2016-09-13 09:54:13 +00:00
|
|
|
*
|
2016-08-29 12:50:41 +00:00
|
|
|
* Trackbook uses osmdroid - OpenStreetMap-Tools for Android
|
|
|
|
* https://github.com/osmdroid/osmdroid
|
|
|
|
*/
|
|
|
|
|
|
|
|
package org.y20k.trackbook;
|
|
|
|
|
|
|
|
import android.Manifest;
|
|
|
|
import android.annotation.TargetApi;
|
2017-05-17 13:43:53 +00:00
|
|
|
import android.app.Activity;
|
2016-09-06 15:27:04 +00:00
|
|
|
import android.content.BroadcastReceiver;
|
|
|
|
import android.content.Context;
|
2016-08-29 12:50:41 +00:00
|
|
|
import android.content.Intent;
|
2016-09-06 15:27:04 +00:00
|
|
|
import android.content.IntentFilter;
|
2016-12-12 17:52:01 +00:00
|
|
|
import android.content.SharedPreferences;
|
2016-08-29 12:50:41 +00:00
|
|
|
import android.content.pm.PackageManager;
|
2016-09-06 15:27:04 +00:00
|
|
|
import android.location.Location;
|
2016-08-29 12:50:41 +00:00
|
|
|
import android.os.Build;
|
|
|
|
import android.os.Bundle;
|
2017-05-31 08:30:29 +00:00
|
|
|
import android.os.Environment;
|
2018-02-21 10:47:09 +00:00
|
|
|
import android.os.Vibrator;
|
2016-12-12 17:52:01 +00:00
|
|
|
import android.preference.PreferenceManager;
|
2016-09-12 12:31:37 +00:00
|
|
|
import android.support.annotation.NonNull;
|
2018-01-12 16:42:47 +00:00
|
|
|
import android.support.annotation.Nullable;
|
2017-11-28 21:02:45 +00:00
|
|
|
import android.support.design.widget.BottomNavigationView;
|
2016-08-29 12:50:41 +00:00
|
|
|
import android.support.design.widget.FloatingActionButton;
|
|
|
|
import android.support.design.widget.Snackbar;
|
2017-05-17 13:43:53 +00:00
|
|
|
import android.support.v4.app.DialogFragment;
|
2016-09-16 15:45:10 +00:00
|
|
|
import android.support.v4.app.Fragment;
|
2018-01-12 16:42:47 +00:00
|
|
|
import android.support.v4.app.FragmentManager;
|
|
|
|
import android.support.v4.app.FragmentPagerAdapter;
|
2016-08-29 12:50:41 +00:00
|
|
|
import android.support.v4.content.ContextCompat;
|
2016-09-06 15:27:04 +00:00
|
|
|
import android.support.v4.content.LocalBroadcastManager;
|
2016-08-29 12:50:41 +00:00
|
|
|
import android.support.v7.app.AppCompatActivity;
|
2017-11-28 21:02:45 +00:00
|
|
|
import android.support.v7.widget.CardView;
|
2018-01-12 16:42:47 +00:00
|
|
|
import android.util.SparseArray;
|
2016-08-29 12:50:41 +00:00
|
|
|
import android.view.MenuItem;
|
|
|
|
import android.view.View;
|
2018-01-12 16:42:47 +00:00
|
|
|
import android.view.ViewGroup;
|
2016-08-29 12:50:41 +00:00
|
|
|
import android.widget.Button;
|
|
|
|
import android.widget.Toast;
|
|
|
|
|
2018-02-19 08:00:47 +00:00
|
|
|
import org.osmdroid.config.Configuration;
|
2017-05-17 13:43:53 +00:00
|
|
|
import org.y20k.trackbook.helpers.DialogHelper;
|
2016-09-12 12:31:37 +00:00
|
|
|
import org.y20k.trackbook.helpers.LogHelper;
|
2018-02-21 10:47:09 +00:00
|
|
|
import org.y20k.trackbook.helpers.NightModeHelper;
|
2016-08-29 12:50:41 +00:00
|
|
|
import org.y20k.trackbook.helpers.TrackbookKeys;
|
2018-01-12 16:42:47 +00:00
|
|
|
import org.y20k.trackbook.layout.NonSwipeableViewPager;
|
2016-08-29 12:50:41 +00:00
|
|
|
|
2018-01-12 16:42:47 +00:00
|
|
|
import java.lang.ref.WeakReference;
|
2016-08-29 12:50:41 +00:00
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.HashMap;
|
|
|
|
import java.util.List;
|
|
|
|
import java.util.Map;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* MainActivity class
|
|
|
|
*/
|
2016-12-12 17:52:01 +00:00
|
|
|
public class MainActivity extends AppCompatActivity implements TrackbookKeys {
|
2016-08-29 12:50:41 +00:00
|
|
|
|
|
|
|
/* Define log tag */
|
2016-09-01 11:45:46 +00:00
|
|
|
private static final String LOG_TAG = MainActivity.class.getSimpleName();
|
2016-08-29 12:50:41 +00:00
|
|
|
|
|
|
|
|
|
|
|
/* Main class variables */
|
2017-11-28 21:02:45 +00:00
|
|
|
private BottomNavigationView mBottomNavigationView;
|
2018-01-12 16:42:47 +00:00
|
|
|
private NonSwipeableViewPager mViewPager;
|
|
|
|
private SectionsPagerAdapter mSectionsPagerAdapter;
|
2016-09-07 10:30:46 +00:00
|
|
|
private boolean mTrackerServiceRunning;
|
2016-08-29 12:50:41 +00:00
|
|
|
private boolean mPermissionsGranted;
|
2016-12-12 17:52:01 +00:00
|
|
|
private boolean mFloatingActionButtonSubMenuVisible;
|
2016-08-29 12:50:41 +00:00
|
|
|
private List<String> mMissingPermissions;
|
2017-11-28 21:02:45 +00:00
|
|
|
private FloatingActionButton mFloatingActionButtonMain;
|
|
|
|
private FloatingActionButton mFloatingActionButtonSubSave;
|
|
|
|
private FloatingActionButton mFloatingActionButtonSubClear;
|
2018-03-15 12:28:52 +00:00
|
|
|
private FloatingActionButton mFloatingActionButtonSubResume;
|
2017-11-28 21:02:45 +00:00
|
|
|
private FloatingActionButton mFloatingActionButtonLocation;
|
|
|
|
private CardView mFloatingActionButtonSubSaveLabel;
|
|
|
|
private CardView mFloatingActionButtonSubClearLabel;
|
2018-03-15 12:28:52 +00:00
|
|
|
private CardView mFloatingActionButtonSubResumeLabel;
|
2016-09-06 15:27:04 +00:00
|
|
|
private BroadcastReceiver mTrackingStoppedReceiver;
|
2016-12-16 21:12:43 +00:00
|
|
|
private int mFloatingActionButtonState;
|
2016-09-30 15:32:54 +00:00
|
|
|
private int mSelectedTab;
|
2016-08-29 12:50:41 +00:00
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void onCreate(Bundle savedInstanceState) {
|
|
|
|
super.onCreate(savedInstanceState);
|
|
|
|
|
2018-01-15 15:50:09 +00:00
|
|
|
// initialize selected tab
|
|
|
|
mSelectedTab = FRAGMENT_ID_MAP;
|
|
|
|
|
2017-05-31 08:30:29 +00:00
|
|
|
// check state of External Storage
|
|
|
|
checkExternalStorageState();
|
|
|
|
|
2016-12-12 17:52:01 +00:00
|
|
|
// load saved state of app
|
2017-01-09 16:56:45 +00:00
|
|
|
loadFloatingActionButtonState(this);
|
2016-08-29 12:50:41 +00:00
|
|
|
|
|
|
|
// check permissions on Android 6 and higher
|
2016-08-30 14:49:54 +00:00
|
|
|
mPermissionsGranted = false;
|
2016-08-29 12:50:41 +00:00
|
|
|
if (Build.VERSION.SDK_INT >= 23) {
|
|
|
|
// check permissions
|
|
|
|
mMissingPermissions = checkPermissions();
|
|
|
|
mPermissionsGranted = mMissingPermissions.size() == 0;
|
|
|
|
} else {
|
|
|
|
mPermissionsGranted = true;
|
|
|
|
}
|
|
|
|
|
2018-01-15 15:50:09 +00:00
|
|
|
// restore state if saved instance is available
|
|
|
|
if (savedInstanceState != null) {
|
|
|
|
mTrackerServiceRunning = savedInstanceState.getBoolean(INSTANCE_TRACKING_STATE, false);
|
|
|
|
mSelectedTab = savedInstanceState.getInt(INSTANCE_SELECTED_TAB, FRAGMENT_ID_MAP);
|
|
|
|
mFloatingActionButtonSubMenuVisible = savedInstanceState.getBoolean(INSTANCE_FAB_SUB_MENU_VISIBLE, false);
|
|
|
|
}
|
|
|
|
|
2016-08-29 12:50:41 +00:00
|
|
|
// set user agent to prevent getting banned from the osm servers
|
2018-02-19 08:00:47 +00:00
|
|
|
Configuration.getInstance().setUserAgentValue(BuildConfig.APPLICATION_ID);
|
2016-08-29 12:50:41 +00:00
|
|
|
|
|
|
|
// set up main layout
|
|
|
|
setupLayout();
|
2016-10-25 14:38:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void onStart() {
|
|
|
|
super.onStart();
|
|
|
|
|
2016-09-06 15:27:04 +00:00
|
|
|
// register broadcast receiver for stopped tracking
|
|
|
|
mTrackingStoppedReceiver = createTrackingStoppedReceiver();
|
|
|
|
IntentFilter trackingStoppedIntentFilter = new IntentFilter(ACTION_TRACKING_STOPPED);
|
|
|
|
LocalBroadcastManager.getInstance(this).registerReceiver(mTrackingStoppedReceiver, trackingStoppedIntentFilter);
|
|
|
|
|
2016-08-29 12:50:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-08-30 14:49:54 +00:00
|
|
|
@Override
|
|
|
|
protected void onResume() {
|
|
|
|
super.onResume();
|
2016-12-16 21:12:43 +00:00
|
|
|
|
2017-01-09 16:56:45 +00:00
|
|
|
// load state of Floating Action Button
|
|
|
|
loadFloatingActionButtonState(this);
|
2016-08-30 14:49:54 +00:00
|
|
|
|
2016-12-19 16:53:20 +00:00
|
|
|
// handle incoming intent (from notification)
|
2016-09-12 12:31:37 +00:00
|
|
|
handleIncomingIntent();
|
2016-09-07 13:48:12 +00:00
|
|
|
|
2016-09-01 11:45:46 +00:00
|
|
|
// if not in onboarding mode: set state of FloatingActionButton
|
2017-11-28 21:02:45 +00:00
|
|
|
if (mFloatingActionButtonMain != null) {
|
2016-09-01 11:45:46 +00:00
|
|
|
setFloatingActionButtonState();
|
|
|
|
}
|
2016-08-30 14:49:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-12-19 16:53:20 +00:00
|
|
|
@Override
|
|
|
|
protected void onPause() {
|
|
|
|
super.onPause();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-09-06 15:27:04 +00:00
|
|
|
@Override
|
|
|
|
public void onDestroy() {
|
|
|
|
super.onDestroy();
|
2016-09-16 15:45:10 +00:00
|
|
|
LogHelper.v(LOG_TAG, "onDestroy called.");
|
2016-09-06 15:27:04 +00:00
|
|
|
|
2017-01-16 14:56:58 +00:00
|
|
|
// reset selected tab
|
|
|
|
mSelectedTab = FRAGMENT_ID_MAP;
|
|
|
|
|
2016-09-06 15:27:04 +00:00
|
|
|
// disable broadcast receiver
|
|
|
|
LocalBroadcastManager.getInstance(this).unregisterReceiver(mTrackingStoppedReceiver);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-08-29 12:50:41 +00:00
|
|
|
@Override
|
2016-09-12 12:31:37 +00:00
|
|
|
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
2016-08-29 12:50:41 +00:00
|
|
|
switch (requestCode) {
|
|
|
|
case REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS: {
|
|
|
|
Map<String, Integer> perms = new HashMap<>();
|
|
|
|
perms.put(Manifest.permission.ACCESS_FINE_LOCATION, PackageManager.PERMISSION_GRANTED);
|
|
|
|
perms.put(Manifest.permission.WRITE_EXTERNAL_STORAGE, PackageManager.PERMISSION_GRANTED);
|
|
|
|
for (int i = 0; i < permissions.length; i++)
|
|
|
|
perms.put(permissions[i], grantResults[i]);
|
|
|
|
|
|
|
|
// check for ACCESS_FINE_LOCATION and WRITE_EXTERNAL_STORAGE
|
|
|
|
Boolean location = perms.get(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED;
|
|
|
|
Boolean storage = perms.get(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;
|
|
|
|
|
|
|
|
if (location && storage) {
|
|
|
|
// permissions granted - notify user
|
|
|
|
Toast.makeText(this, R.string.toast_message_permissions_granted, Toast.LENGTH_SHORT).show();
|
|
|
|
mPermissionsGranted = true;
|
|
|
|
// switch to main map layout
|
|
|
|
setupLayout();
|
|
|
|
} else {
|
|
|
|
// permissions denied - notify user
|
|
|
|
Toast.makeText(this, R.string.toast_message_unable_to_start_app, Toast.LENGTH_SHORT).show();
|
|
|
|
mPermissionsGranted = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-09-27 14:08:45 +00:00
|
|
|
@Override
|
2016-12-12 17:52:01 +00:00
|
|
|
protected void onSaveInstanceState(Bundle outState) {
|
|
|
|
outState.putBoolean(INSTANCE_TRACKING_STATE, mTrackerServiceRunning);
|
|
|
|
outState.putInt(INSTANCE_SELECTED_TAB, mSelectedTab);
|
2016-12-16 21:12:43 +00:00
|
|
|
outState.putBoolean(INSTANCE_FAB_SUB_MENU_VISIBLE, mFloatingActionButtonSubMenuVisible);
|
2016-12-12 17:52:01 +00:00
|
|
|
super.onSaveInstanceState(outState);
|
|
|
|
}
|
2016-09-27 14:08:45 +00:00
|
|
|
|
|
|
|
|
2018-01-15 15:50:09 +00:00
|
|
|
/* Handles FloatingActionButton dialog results - called by MainActivityMapFragment after Saving and/or clearing the map */
|
2017-05-17 13:43:53 +00:00
|
|
|
public void onFloatingActionButtonResult(int requestCode, int resultCode) {
|
|
|
|
switch(requestCode) {
|
|
|
|
case RESULT_SAVE_DIALOG:
|
|
|
|
if (resultCode == Activity.RESULT_OK) {
|
|
|
|
// user chose SAVE
|
|
|
|
handleStateAfterSave();
|
2018-01-15 15:50:09 +00:00
|
|
|
LogHelper.v(LOG_TAG, "Save dialog result: SAVE");
|
2017-05-17 13:43:53 +00:00
|
|
|
} else if (resultCode == Activity.RESULT_CANCELED){
|
|
|
|
LogHelper.v(LOG_TAG, "Save dialog result: CANCEL");
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case RESULT_CLEAR_DIALOG:
|
|
|
|
if (resultCode == Activity.RESULT_OK) {
|
|
|
|
// user chose CLEAR
|
|
|
|
handleStateAfterClear();
|
2018-01-15 15:50:09 +00:00
|
|
|
LogHelper.v(LOG_TAG, "Save dialog result: CLEAR");
|
2017-05-17 13:43:53 +00:00
|
|
|
} else if (resultCode == Activity.RESULT_CANCELED){
|
|
|
|
LogHelper.v(LOG_TAG, "Clear map: User chose CANCEL.");
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Handles the visual state after a save action */
|
|
|
|
private void handleStateAfterSave() {
|
2018-01-15 15:50:09 +00:00
|
|
|
// display and update tracks tab
|
|
|
|
mBottomNavigationView.setSelectedItemId(R.id.navigation_last_tracks);
|
2017-05-17 13:43:53 +00:00
|
|
|
|
|
|
|
// dismiss notification
|
2018-01-21 21:28:32 +00:00
|
|
|
startTrackerService(ACTION_DISMISS, null);
|
|
|
|
|
|
|
|
// Intent intent = new Intent(this, TrackerService.class);
|
|
|
|
// intent.setAction(ACTION_DISMISS);
|
|
|
|
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
|
|
// startForegroundService(intent);
|
|
|
|
// }
|
2017-05-17 13:43:53 +00:00
|
|
|
|
|
|
|
// hide Floating Action Button sub menu
|
|
|
|
showFloatingActionButtonMenu(false);
|
|
|
|
|
|
|
|
// update Floating Action Button icon
|
|
|
|
mFloatingActionButtonState = FAB_STATE_DEFAULT;
|
|
|
|
setFloatingActionButtonState();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-01-21 21:28:32 +00:00
|
|
|
/* Start/stop tracker service */
|
|
|
|
private void startTrackerService(String intentAction, @Nullable Location lastLocation) {
|
|
|
|
// build intent
|
|
|
|
Intent intent = new Intent(this, TrackerService.class);
|
|
|
|
intent.setAction(intentAction);
|
|
|
|
if (lastLocation != null && intentAction.equals(ACTION_START)) {
|
|
|
|
intent.putExtra(EXTRA_LAST_LOCATION, lastLocation);
|
|
|
|
}
|
|
|
|
|
2018-01-21 21:54:34 +00:00
|
|
|
// communicate with service
|
|
|
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && intentAction.equals(ACTION_START)) {
|
|
|
|
// ... start service in foreground to prevent it being killed on Oreo
|
2018-01-21 21:28:32 +00:00
|
|
|
startForegroundService(intent);
|
|
|
|
} else {
|
|
|
|
startService(intent);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2017-05-17 13:43:53 +00:00
|
|
|
/* Handles the visual state after a save action */
|
|
|
|
private void handleStateAfterClear() {
|
|
|
|
// notify user
|
|
|
|
Toast.makeText(this, getString(R.string.toast_message_track_clear), Toast.LENGTH_LONG).show();
|
|
|
|
|
|
|
|
// dismiss notification
|
2018-01-21 21:28:32 +00:00
|
|
|
startTrackerService(ACTION_DISMISS, null);
|
|
|
|
|
2017-05-17 13:43:53 +00:00
|
|
|
// hide Floating Action Button sub menu
|
|
|
|
showFloatingActionButtonMenu(false);
|
|
|
|
|
|
|
|
// update Floating Action Button icon
|
|
|
|
mFloatingActionButtonState = FAB_STATE_DEFAULT;
|
|
|
|
setFloatingActionButtonState();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-01-09 16:56:45 +00:00
|
|
|
/* Loads state of Floating Action Button from preferences */
|
|
|
|
private void loadFloatingActionButtonState(Context context) {
|
2016-12-12 17:52:01 +00:00
|
|
|
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context);
|
2017-01-09 16:56:45 +00:00
|
|
|
mFloatingActionButtonState = settings.getInt(PREFS_FAB_STATE, FAB_STATE_DEFAULT);
|
|
|
|
}
|
|
|
|
|
2017-01-25 13:19:50 +00:00
|
|
|
|
2018-03-15 12:28:52 +00:00
|
|
|
/* Handles tap on the button "save" */
|
2018-01-15 15:50:09 +00:00
|
|
|
private void handleSaveButtonClick() {
|
|
|
|
// save button click is handled by onActivityResult in MainActivityMapFragment
|
|
|
|
MainActivityMapFragment mainActivityMapFragment = (MainActivityMapFragment) mSectionsPagerAdapter.getFragment(FRAGMENT_ID_MAP);
|
|
|
|
mainActivityMapFragment.onActivityResult(RESULT_SAVE_DIALOG, Activity.RESULT_OK, getIntent());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Handles tap on the button "clear" */
|
|
|
|
private void handleClearButtonClick() {
|
|
|
|
// prepare delete dialog
|
|
|
|
int dialogTitle = -1;
|
|
|
|
String dialogMessage = getString(R.string.dialog_clear_content);
|
|
|
|
int dialogPositiveButton = R.string.dialog_clear_action_clear;
|
|
|
|
int dialogNegativeButton = R.string.dialog_default_action_cancel;
|
|
|
|
// show delete dialog
|
|
|
|
MainActivityMapFragment mainActivityMapFragment = (MainActivityMapFragment) mSectionsPagerAdapter.getFragment(FRAGMENT_ID_MAP);
|
|
|
|
DialogFragment dialogFragment = DialogHelper.newInstance(dialogTitle, dialogMessage, dialogPositiveButton, dialogNegativeButton);
|
|
|
|
dialogFragment.setTargetFragment(mainActivityMapFragment, RESULT_CLEAR_DIALOG);
|
|
|
|
dialogFragment.show(getSupportFragmentManager(), "ClearDialog");
|
|
|
|
// results of dialog are handled by onActivityResult in MainActivityMapFragment
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-03-15 12:28:52 +00:00
|
|
|
/* Handles tap on the button "resume" */
|
|
|
|
private void handleResumeButtonClick() {
|
|
|
|
// todo implement
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-01-15 15:50:09 +00:00
|
|
|
// /* Saves state of Floating Action Button */ // not needed tracker service saves state
|
2017-08-15 08:23:03 +00:00
|
|
|
// private void saveFloatingActionButtonState(Context context) {
|
|
|
|
// SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context);
|
|
|
|
// SharedPreferences.Editor editor = settings.edit();
|
|
|
|
// editor.putInt(PREFS_FAB_STATE, mFloatingActionButtonState);
|
|
|
|
// editor.apply();
|
|
|
|
// }
|
2016-09-27 14:08:45 +00:00
|
|
|
|
|
|
|
|
2016-08-29 12:50:41 +00:00
|
|
|
/* Set up main layout */
|
|
|
|
private void setupLayout() {
|
2016-09-16 15:45:10 +00:00
|
|
|
if (mPermissionsGranted) {
|
|
|
|
// point to the main map layout
|
2016-12-12 17:52:01 +00:00
|
|
|
setContentView(R.layout.activity_main);
|
2016-09-16 15:45:10 +00:00
|
|
|
|
2018-01-12 16:42:47 +00:00
|
|
|
// create adapter that returns fragments for the maim map and the last track display
|
|
|
|
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
|
|
|
|
|
|
|
|
// set up the ViewPager with the sections adapter.
|
2018-01-16 13:27:50 +00:00
|
|
|
mViewPager = (NonSwipeableViewPager) findViewById(R.id.fragmentContainer);
|
2018-01-12 16:42:47 +00:00
|
|
|
mViewPager.setAdapter(mSectionsPagerAdapter);
|
|
|
|
|
2017-11-28 21:02:45 +00:00
|
|
|
// setup bottom navigation
|
|
|
|
mBottomNavigationView = findViewById(R.id.navigation);
|
|
|
|
mBottomNavigationView.setOnNavigationItemSelectedListener(getOnNavigationItemSelectedListener());
|
2016-09-16 15:45:10 +00:00
|
|
|
|
2016-12-12 17:52:01 +00:00
|
|
|
// get references to the record button and show/hide its sub menu
|
2017-11-28 21:02:45 +00:00
|
|
|
mFloatingActionButtonMain = findViewById(R.id.fabMainButton);
|
2018-01-16 13:27:50 +00:00
|
|
|
mFloatingActionButtonLocation = findViewById(R.id.fabLocationButton);
|
2017-11-28 21:02:45 +00:00
|
|
|
mFloatingActionButtonSubSave = findViewById(R.id.fabSubMenuButtonSave);
|
|
|
|
mFloatingActionButtonSubSaveLabel = findViewById(R.id.fabSubMenuLabelSave);
|
|
|
|
mFloatingActionButtonSubClear = findViewById(R.id.fabSubMenuButtonClear);
|
|
|
|
mFloatingActionButtonSubClearLabel = findViewById(R.id.fabSubMenuLabelClear);
|
2018-03-15 12:28:52 +00:00
|
|
|
mFloatingActionButtonSubResume = findViewById(R.id.fabSubMenuButtonResume);
|
|
|
|
mFloatingActionButtonSubResumeLabel = findViewById(R.id.fabSubMenuLabelResume);
|
2016-12-12 17:52:01 +00:00
|
|
|
if (mFloatingActionButtonSubMenuVisible) {
|
|
|
|
showFloatingActionButtonMenu(true);
|
|
|
|
} else {
|
|
|
|
showFloatingActionButtonMenu(false);
|
|
|
|
}
|
2016-09-16 15:45:10 +00:00
|
|
|
|
2018-01-15 15:50:09 +00:00
|
|
|
// restore selected tab
|
|
|
|
if (mSelectedTab == FRAGMENT_ID_TRACKS) {
|
|
|
|
mBottomNavigationView.setSelectedItemId(R.id.navigation_last_tracks);
|
|
|
|
} else {
|
|
|
|
mBottomNavigationView.setSelectedItemId(R.id.navigation_map);
|
|
|
|
}
|
|
|
|
|
2017-11-29 20:45:50 +00:00
|
|
|
// add listeners to buttons
|
|
|
|
addListenersToViews();
|
2017-11-28 21:02:45 +00:00
|
|
|
|
2016-09-16 15:45:10 +00:00
|
|
|
} else {
|
|
|
|
// point to the on main onboarding layout
|
|
|
|
setContentView(R.layout.activity_main_onboarding);
|
|
|
|
|
|
|
|
// show the okay button and attach listener
|
2017-01-11 20:52:45 +00:00
|
|
|
Button okayButton = (Button) findViewById(R.id.button_okay);
|
|
|
|
okayButton.setOnClickListener(new View.OnClickListener() {
|
2016-09-16 15:45:10 +00:00
|
|
|
@TargetApi(Build.VERSION_CODES.M)
|
|
|
|
@Override
|
|
|
|
public void onClick(View view) {
|
|
|
|
if (mMissingPermissions != null && !mMissingPermissions.isEmpty()) {
|
|
|
|
// request permissions
|
|
|
|
String[] params = mMissingPermissions.toArray(new String[mMissingPermissions.size()]);
|
|
|
|
requestPermissions(params, REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-11-29 20:45:50 +00:00
|
|
|
/* Add listeners to ui buttons */
|
|
|
|
private void addListenersToViews() {
|
|
|
|
|
|
|
|
mFloatingActionButtonMain.setOnClickListener(new View.OnClickListener() {
|
|
|
|
@Override
|
|
|
|
public void onClick(View view) {
|
|
|
|
handleFloatingActionButtonClick(view);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
mFloatingActionButtonSubSave.setOnClickListener(new View.OnClickListener() {
|
|
|
|
@Override
|
|
|
|
public void onClick(View view) {
|
|
|
|
handleSaveButtonClick();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
mFloatingActionButtonSubSaveLabel.setOnClickListener(new View.OnClickListener() {
|
|
|
|
@Override
|
|
|
|
public void onClick(View view) {
|
|
|
|
handleSaveButtonClick();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
mFloatingActionButtonSubClear.setOnClickListener(new View.OnClickListener() {
|
|
|
|
@Override
|
|
|
|
public void onClick(View view) {
|
|
|
|
handleClearButtonClick();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
mFloatingActionButtonSubClearLabel.setOnClickListener(new View.OnClickListener() {
|
|
|
|
@Override
|
|
|
|
public void onClick(View view) {
|
|
|
|
handleClearButtonClick();
|
|
|
|
}
|
|
|
|
});
|
2018-03-15 12:28:52 +00:00
|
|
|
mFloatingActionButtonSubResume.setOnClickListener(new View.OnClickListener() {
|
|
|
|
@Override
|
|
|
|
public void onClick(View view) {
|
|
|
|
handleResumeButtonClick();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
mFloatingActionButtonSubResumeLabel.setOnClickListener(new View.OnClickListener() {
|
|
|
|
@Override
|
|
|
|
public void onClick(View view) {
|
|
|
|
handleResumeButtonClick();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
|
2017-11-29 20:45:50 +00:00
|
|
|
mFloatingActionButtonLocation.setOnClickListener(new View.OnClickListener() {
|
|
|
|
@Override
|
|
|
|
public void onClick(View view) {
|
2018-01-12 16:42:47 +00:00
|
|
|
MainActivityMapFragment mainActivityMapFragment = (MainActivityMapFragment) mSectionsPagerAdapter.getFragment(FRAGMENT_ID_MAP);
|
2017-11-29 20:45:50 +00:00
|
|
|
mainActivityMapFragment.handleShowMyLocation();
|
|
|
|
}
|
|
|
|
});
|
2018-02-21 10:47:09 +00:00
|
|
|
mFloatingActionButtonLocation.setOnLongClickListener(new View.OnLongClickListener() {
|
|
|
|
@Override
|
|
|
|
public boolean onLongClick(View v) {
|
|
|
|
longPressFeedback(R.string.toastmessage_long_press_night_mode_switch);
|
|
|
|
NightModeHelper.switchToOpposite(MainActivity.this);
|
2018-02-23 12:16:26 +00:00
|
|
|
recreate();
|
2018-02-21 10:47:09 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
});
|
2017-11-29 20:45:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-08-29 12:50:41 +00:00
|
|
|
/* Handles tap on the record button */
|
|
|
|
private void handleFloatingActionButtonClick(View view) {
|
|
|
|
|
2016-12-16 21:12:43 +00:00
|
|
|
switch (mFloatingActionButtonState) {
|
|
|
|
case FAB_STATE_DEFAULT:
|
2016-08-29 12:50:41 +00:00
|
|
|
|
2017-10-16 08:20:59 +00:00
|
|
|
// get last location from MainActivity Fragment // todo check -> may produce NullPointerException
|
2018-01-12 16:42:47 +00:00
|
|
|
MainActivityMapFragment mainActivityMapFragment = (MainActivityMapFragment) mSectionsPagerAdapter.getFragment(FRAGMENT_ID_MAP);
|
2017-01-17 09:40:47 +00:00
|
|
|
Location lastLocation = mainActivityMapFragment.getCurrentBestLocation();
|
2016-12-12 17:52:01 +00:00
|
|
|
|
2016-12-16 21:12:43 +00:00
|
|
|
if (lastLocation != null) {
|
2018-02-19 08:00:47 +00:00
|
|
|
// change state
|
|
|
|
mTrackerServiceRunning = true;
|
|
|
|
mFloatingActionButtonState = FAB_STATE_RECORDING;
|
|
|
|
setFloatingActionButtonState();
|
|
|
|
|
|
|
|
// show snackbar
|
|
|
|
Snackbar.make(view, R.string.snackbar_message_tracking_started, Snackbar.LENGTH_SHORT).setAction("Action", null).show();
|
|
|
|
|
2016-12-16 21:12:43 +00:00
|
|
|
// start tracker service
|
2018-01-21 21:28:32 +00:00
|
|
|
startTrackerService(ACTION_START, lastLocation);
|
|
|
|
|
2016-12-16 21:12:43 +00:00
|
|
|
} else {
|
|
|
|
Toast.makeText(this, getString(R.string.toast_message_location_services_not_ready), Toast.LENGTH_LONG).show();
|
|
|
|
// change state back
|
|
|
|
mTrackerServiceRunning = false;
|
|
|
|
}
|
2016-08-29 12:50:41 +00:00
|
|
|
|
2016-12-16 21:12:43 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case FAB_STATE_RECORDING:
|
|
|
|
// show snackbar
|
|
|
|
Snackbar.make(view, R.string.snackbar_message_tracking_stopped, Snackbar.LENGTH_SHORT).setAction("Action", null).show();
|
2016-09-06 15:27:04 +00:00
|
|
|
|
2016-12-16 21:12:43 +00:00
|
|
|
// change state
|
|
|
|
// --> is handled by broadcast receiver
|
2016-08-29 12:50:41 +00:00
|
|
|
|
2016-12-16 21:12:43 +00:00
|
|
|
// stop tracker service
|
2018-01-21 21:28:32 +00:00
|
|
|
startTrackerService(ACTION_STOP, null);
|
|
|
|
|
2016-12-16 21:12:43 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case FAB_STATE_SAVE:
|
2018-01-22 14:17:33 +00:00
|
|
|
// toggle visibility floating action button sub menu
|
|
|
|
showFloatingActionButtonMenu(!mFloatingActionButtonSubMenuVisible);
|
2016-12-16 21:12:43 +00:00
|
|
|
|
|
|
|
break;
|
2016-09-26 11:43:26 +00:00
|
|
|
|
2016-08-29 12:50:41 +00:00
|
|
|
}
|
2016-09-01 11:45:46 +00:00
|
|
|
|
2017-10-16 08:20:59 +00:00
|
|
|
// update tracking state in MainActivityMapFragment // todo check -> may produce NullPointerException
|
2018-01-12 16:42:47 +00:00
|
|
|
MainActivityMapFragment mainActivityMapFragment = (MainActivityMapFragment) mSectionsPagerAdapter.getFragment(FRAGMENT_ID_MAP);
|
2017-01-17 09:40:47 +00:00
|
|
|
mainActivityMapFragment.setTrackingState(mTrackerServiceRunning);
|
2016-08-29 12:50:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-08-30 14:49:54 +00:00
|
|
|
/* Set state of FloatingActionButton */
|
|
|
|
private void setFloatingActionButtonState() {
|
2016-12-16 21:12:43 +00:00
|
|
|
|
|
|
|
switch (mFloatingActionButtonState) {
|
|
|
|
case FAB_STATE_DEFAULT:
|
2017-11-28 21:02:45 +00:00
|
|
|
mFloatingActionButtonMain.setImageResource(R.drawable.ic_fiber_manual_record_white_24dp);
|
2016-12-16 21:12:43 +00:00
|
|
|
break;
|
|
|
|
case FAB_STATE_RECORDING:
|
2017-11-28 21:02:45 +00:00
|
|
|
mFloatingActionButtonMain.setImageResource(R.drawable.ic_fiber_manual_record_red_24dp);
|
2016-12-16 21:12:43 +00:00
|
|
|
break;
|
|
|
|
case FAB_STATE_SAVE:
|
2017-11-28 21:02:45 +00:00
|
|
|
mFloatingActionButtonMain.setImageResource(R.drawable.ic_save_white_24dp);
|
2016-12-16 21:12:43 +00:00
|
|
|
break;
|
|
|
|
default:
|
2017-11-28 21:02:45 +00:00
|
|
|
mFloatingActionButtonMain.setImageResource(R.drawable.ic_fiber_manual_record_white_24dp);
|
2016-12-16 21:12:43 +00:00
|
|
|
break;
|
2016-08-30 14:49:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-12-12 17:52:01 +00:00
|
|
|
/* Shows (and hides) the sub menu of the floating action button */
|
|
|
|
private void showFloatingActionButtonMenu(boolean visible) {
|
|
|
|
if (visible) {
|
2018-03-15 12:28:52 +00:00
|
|
|
mFloatingActionButtonSubResume.setVisibility(View.VISIBLE);
|
|
|
|
mFloatingActionButtonSubResumeLabel.setVisibility(View.VISIBLE);
|
2017-11-28 21:02:45 +00:00
|
|
|
mFloatingActionButtonSubClear.setVisibility(View.VISIBLE);
|
|
|
|
mFloatingActionButtonSubClearLabel.setVisibility(View.VISIBLE);
|
|
|
|
mFloatingActionButtonSubSave.setVisibility(View.VISIBLE);
|
|
|
|
mFloatingActionButtonSubSaveLabel.setVisibility(View.VISIBLE);
|
2016-12-12 17:52:01 +00:00
|
|
|
mFloatingActionButtonSubMenuVisible = true;
|
|
|
|
} else {
|
2018-03-15 12:28:52 +00:00
|
|
|
mFloatingActionButtonSubResume.setVisibility(View.INVISIBLE);
|
|
|
|
mFloatingActionButtonSubResumeLabel.setVisibility(View.INVISIBLE);
|
2017-11-28 21:02:45 +00:00
|
|
|
mFloatingActionButtonSubClear.setVisibility(View.INVISIBLE);
|
|
|
|
mFloatingActionButtonSubClearLabel.setVisibility(View.INVISIBLE);
|
|
|
|
mFloatingActionButtonSubSaveLabel.setVisibility(View.INVISIBLE);
|
|
|
|
mFloatingActionButtonSubSave.setVisibility(View.INVISIBLE);
|
2016-12-12 17:52:01 +00:00
|
|
|
mFloatingActionButtonSubMenuVisible = false;
|
|
|
|
}
|
2017-11-28 21:02:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Handles taps on the bottom navigation */
|
|
|
|
private BottomNavigationView.OnNavigationItemSelectedListener getOnNavigationItemSelectedListener() {
|
|
|
|
return new BottomNavigationView.OnNavigationItemSelectedListener() {
|
|
|
|
@Override
|
|
|
|
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
|
|
|
|
switch (item.getItemId()) {
|
|
|
|
case R.id.navigation_map:
|
|
|
|
// show the Floating Action Button
|
|
|
|
mFloatingActionButtonMain.show();
|
|
|
|
|
|
|
|
// show the my location button
|
|
|
|
mFloatingActionButtonLocation.show();
|
|
|
|
|
|
|
|
// show map fragment
|
|
|
|
mSelectedTab = FRAGMENT_ID_MAP;
|
2018-01-12 16:42:47 +00:00
|
|
|
mViewPager.setCurrentItem(mSelectedTab);
|
2017-11-28 21:02:45 +00:00
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
case R.id.navigation_last_tracks:
|
|
|
|
// hide the Floating Action Button - and its sub menu
|
|
|
|
mFloatingActionButtonMain.hide();
|
|
|
|
showFloatingActionButtonMenu(false);
|
|
|
|
|
|
|
|
// hide the my location button
|
|
|
|
mFloatingActionButtonLocation.hide();
|
|
|
|
|
|
|
|
// show tracks fragment
|
|
|
|
mSelectedTab = FRAGMENT_ID_TRACKS;
|
2018-01-12 16:42:47 +00:00
|
|
|
mViewPager.setCurrentItem(mSelectedTab);
|
2017-11-28 21:02:45 +00:00
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
default:
|
|
|
|
// show the Floating Action Button
|
|
|
|
mFloatingActionButtonMain.show();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
2016-12-12 17:52:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-09-12 12:31:37 +00:00
|
|
|
/* Handles new incoming intents */
|
|
|
|
private void handleIncomingIntent() {
|
|
|
|
Intent intent = getIntent();
|
2017-01-25 13:19:50 +00:00
|
|
|
LogHelper.v(LOG_TAG, "Main Activity received intent. Content: " + intent.toString());
|
2016-09-12 12:31:37 +00:00
|
|
|
String intentAction = intent.getAction();
|
|
|
|
switch (intentAction) {
|
|
|
|
case ACTION_SHOW_MAP:
|
2017-01-25 13:19:50 +00:00
|
|
|
// show map fragment
|
2018-01-15 15:50:09 +00:00
|
|
|
mBottomNavigationView.setSelectedItemId(R.id.navigation_map);
|
2017-01-21 10:32:51 +00:00
|
|
|
|
|
|
|
// clear intent
|
|
|
|
intent.setAction(ACTION_DEFAULT);
|
|
|
|
|
2016-09-12 12:31:37 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2016-09-07 13:48:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-02-21 10:47:09 +00:00
|
|
|
/* Inform user and give haptic feedback (vibration) */
|
|
|
|
private void longPressFeedback(int stringResource) {
|
|
|
|
// inform user
|
|
|
|
Toast.makeText(this, stringResource, Toast.LENGTH_LONG).show();
|
|
|
|
// vibrate 50 milliseconds
|
|
|
|
Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
|
|
|
|
v.vibrate(50);
|
|
|
|
// v.vibrate(VibrationEffect.createOneShot(50, DEFAULT_AMPLITUDE)); // todo check if there is a support library vibrator
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2016-08-29 12:50:41 +00:00
|
|
|
/* Check which permissions have been granted */
|
|
|
|
private List<String> checkPermissions() {
|
|
|
|
List<String> permissions = new ArrayList<>();
|
|
|
|
|
|
|
|
// check for location permission
|
|
|
|
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
|
|
|
|
// add missing permission
|
|
|
|
permissions.add(Manifest.permission.ACCESS_FINE_LOCATION);
|
|
|
|
}
|
|
|
|
|
|
|
|
// check for storage permission
|
|
|
|
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
|
|
|
|
// add missing permission
|
|
|
|
permissions.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
|
|
|
|
}
|
|
|
|
|
|
|
|
return permissions;
|
|
|
|
}
|
|
|
|
|
2016-09-06 15:27:04 +00:00
|
|
|
|
|
|
|
/* Creates receiver for stopped tracking */
|
|
|
|
private BroadcastReceiver createTrackingStoppedReceiver() {
|
|
|
|
return new BroadcastReceiver() {
|
|
|
|
@Override
|
|
|
|
public void onReceive(Context context, Intent intent) {
|
|
|
|
// change state
|
2016-09-07 10:30:46 +00:00
|
|
|
mTrackerServiceRunning = false;
|
2016-12-16 21:12:43 +00:00
|
|
|
mFloatingActionButtonState = FAB_STATE_SAVE;
|
2016-09-06 15:27:04 +00:00
|
|
|
setFloatingActionButtonState();
|
|
|
|
|
2017-10-16 08:20:59 +00:00
|
|
|
// pass tracking state to MainActivityMapFragment // todo check -> may produce NullPointerException
|
2018-01-12 16:42:47 +00:00
|
|
|
MainActivityMapFragment mainActivityMapFragment = (MainActivityMapFragment) mSectionsPagerAdapter.getFragment(FRAGMENT_ID_MAP);
|
2017-01-17 09:40:47 +00:00
|
|
|
mainActivityMapFragment.setTrackingState(false);
|
2016-09-06 15:27:04 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2016-09-16 15:45:10 +00:00
|
|
|
|
2017-05-31 08:30:29 +00:00
|
|
|
/* Checks the state of External Storage */
|
|
|
|
private void checkExternalStorageState() {
|
|
|
|
|
|
|
|
String state = Environment.getExternalStorageState();
|
|
|
|
if (!state.equals(Environment.MEDIA_MOUNTED)) {
|
|
|
|
LogHelper.e(LOG_TAG, "Error: Unable to mount External Storage. Current state: " + state);
|
|
|
|
|
|
|
|
// move MainActivity to back
|
|
|
|
moveTaskToBack(true);
|
|
|
|
|
|
|
|
// shutting down app
|
|
|
|
android.os.Process.killProcess(android.os.Process.myPid());
|
|
|
|
System.exit(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-01-12 16:42:47 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Inner class: SectionsPagerAdapter that returns a fragment corresponding to one of the tabs.
|
|
|
|
* see also: https://developer.android.com/reference/android/support/v4/app/FragmentPagerAdapter.html
|
|
|
|
* and: http://www.truiton.com/2015/12/android-activity-fragment-communication/
|
|
|
|
*/
|
|
|
|
public class SectionsPagerAdapter extends FragmentPagerAdapter {
|
|
|
|
|
|
|
|
private final SparseArray<WeakReference<Fragment>> instantiatedFragments = new SparseArray<>();
|
|
|
|
|
|
|
|
public SectionsPagerAdapter(FragmentManager fm) {
|
|
|
|
super(fm);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public Fragment getItem(int position) {
|
|
|
|
// getItem is called to instantiate the fragment for the given page.
|
|
|
|
switch (position) {
|
|
|
|
case FRAGMENT_ID_MAP:
|
|
|
|
return new MainActivityMapFragment();
|
|
|
|
case FRAGMENT_ID_TRACKS:
|
|
|
|
return new MainActivityTrackFragment();
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public int getCount() {
|
|
|
|
// Show 2 total pages.
|
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public CharSequence getPageTitle(int position) {
|
|
|
|
switch (position) {
|
|
|
|
case FRAGMENT_ID_MAP:
|
|
|
|
return getString(R.string.tab_map);
|
|
|
|
case FRAGMENT_ID_TRACKS:
|
|
|
|
return getString(R.string.tab_last_tracks);
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2018-01-16 13:27:50 +00:00
|
|
|
@NonNull
|
2018-01-12 16:42:47 +00:00
|
|
|
@Override
|
|
|
|
public Object instantiateItem(final ViewGroup container, final int position) {
|
|
|
|
final Fragment fragment = (Fragment) super.instantiateItem(container, position);
|
|
|
|
instantiatedFragments.put(position, new WeakReference<>(fragment));
|
|
|
|
return fragment;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void destroyItem(final ViewGroup container, final int position, final Object object) {
|
|
|
|
instantiatedFragments.remove(position);
|
|
|
|
super.destroyItem(container, position, object);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Nullable
|
|
|
|
public Fragment getFragment(final int position) {
|
|
|
|
final WeakReference<Fragment> wr = instantiatedFragments.get(position);
|
|
|
|
if (wr != null) {
|
|
|
|
return wr.get();
|
|
|
|
} else {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
/**
|
|
|
|
* End of inner class
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
2016-08-29 12:50:41 +00:00
|
|
|
}
|