From 62814aaa54cad7024e0dd1f142c6e59ea1f4943a Mon Sep 17 00:00:00 2001 From: Mieszko Date: Wed, 19 Sep 2018 21:46:15 +0200 Subject: [PATCH] Add google background service --- app/build.gradle | 2 +- app/src/main/AndroidManifest.xml | 13 +- .../findmytutor/activity/MainActivity.java | 458 ++++++------------ .../findmytutor/service/GoogleService.java | 158 ++++++ .../findmytutor/service/LocationService.java | 397 --------------- app/src/main/res/layout/activity_main.xml | 66 +-- app/src/main/res/layout/fragment_map.xml | 1 + 7 files changed, 317 insertions(+), 778 deletions(-) create mode 100644 app/src/main/java/com/uam/wmi/findmytutor/service/GoogleService.java delete mode 100644 app/src/main/java/com/uam/wmi/findmytutor/service/LocationService.java diff --git a/app/build.gradle b/app/build.gradle index 5bd7c0a..a0d8d56 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -8,7 +8,7 @@ android { } defaultConfig { applicationId "com.uam.wmi.findmytutor" - minSdkVersion 26 + minSdkVersion 23 targetSdkVersion 27 versionCode 1 versionName "1.0" diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ad432e3..fa9eceb 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -2,15 +2,9 @@ - - - - - - - + - /> + + \ No newline at end of file diff --git a/app/src/main/java/com/uam/wmi/findmytutor/activity/MainActivity.java b/app/src/main/java/com/uam/wmi/findmytutor/activity/MainActivity.java index c1173fc..4bb0699 100644 --- a/app/src/main/java/com/uam/wmi/findmytutor/activity/MainActivity.java +++ b/app/src/main/java/com/uam/wmi/findmytutor/activity/MainActivity.java @@ -1,133 +1,115 @@ package com.uam.wmi.findmytutor.activity; -import android.Manifest; -import android.app.Fragment; -import android.app.FragmentTransaction; -import android.app.PendingIntent; + +import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; +import android.content.IntentFilter; import android.content.SharedPreferences; import android.content.pm.PackageManager; -import android.net.Uri; -import android.os.Bundle; +import android.location.Address; +import android.location.Geocoder; import android.preference.PreferenceManager; -import android.provider.Settings; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; import android.support.design.widget.BottomNavigationView; -import android.support.design.widget.FloatingActionButton; -import android.support.design.widget.Snackbar; import android.support.v4.app.ActivityCompat; - +import android.support.v4.content.ContextCompat; import android.support.v7.app.AppCompatActivity; -import android.util.Log; -import android.view.MenuItem; +import android.os.Bundle; + import android.view.View; -import android.widget.Button; import android.widget.FrameLayout; import android.widget.TextView; +import android.widget.Toast; + +import com.uam.wmi.findmytutor.service.GoogleService; + +import java.io.IOException; +import java.util.List; +import java.util.Locale; + +import android.support.design.widget.FloatingActionButton; + + +import android.app.Fragment; +import android.app.FragmentTransaction; + +import android.support.annotation.NonNull; + +import android.view.MenuItem; -import com.google.android.gms.common.ConnectionResult; import com.mapbox.mapboxsdk.Mapbox; -import com.uam.wmi.findmytutor.BuildConfig; +import com.mapbox.mapboxsdk.maps.MapView; import com.uam.wmi.findmytutor.R; -import com.uam.wmi.findmytutor.service.LocationRequestHelper; -import com.uam.wmi.findmytutor.service.LocationResultHelper; -import com.uam.wmi.findmytutor.service.LocationUpdatesBroadcastReceiver; - -import com.google.android.gms.common.api.GoogleApiClient; -import com.google.android.gms.location.LocationRequest; -import com.google.android.gms.location.LocationServices; +import com.uam.wmi.findmytutor.model.Coordinate; -public class MainActivity extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks, - GoogleApiClient.OnConnectionFailedListener, - SharedPreferences.OnSharedPreferenceChangeListener { - - - private static final String TAG = MainActivity.class.getSimpleName(); - private static final int REQUEST_PERMISSIONS_REQUEST_CODE = 34; - /** - * The desired interval for location updates. Inexact. Updates may be more or less frequent. - */ - // FIXME: 5/16/17 - private static final long UPDATE_INTERVAL = 10 * 1000; - - /** - * The fastest rate for active location updates. Updates will never be more frequent - * than this value, but they may be less frequent. - */ - // FIXME: 5/14/17 - private static final long FASTEST_UPDATE_INTERVAL = UPDATE_INTERVAL / 2; - - /** - * The max time before batched results are delivered by location services. Results may be - * delivered sooner than this interval. - */ - private static final long MAX_WAIT_TIME = UPDATE_INTERVAL * 3; - - /** - * Stores parameters for requests to the FusedLocationProviderApi. - */ - private LocationRequest mLocationRequest; - - /** - * The entry point to Google Play Services. - */ - private GoogleApiClient mGoogleApiClient; +public class MainActivity extends AppCompatActivity { private BottomNavigationView mMainNav; private FrameLayout mMainFrame; - + private boolean isTutor; private MapFragment mapFragment; private NotificationFragment notificationFragment; private ProfileFragment profileFragment; - // UI Widgets. - private Button mRequestUpdatesButton; - private Button mRemoveUpdatesButton; - private TextView mLocationUpdatesResultView; + private static final int REQUEST_PERMISSIONS = 100; + boolean boolean_permission; + TextView tv_latitude, tv_longitude, tv_address, tv_area, tv_locality; + SharedPreferences mPref; + SharedPreferences.Editor medit; + Double latitude, longitude; + Geocoder geocoder; + + + private MapView mapView; + + public List getCoordinates() { + return this.coordinates; + } + + public void setCoordinates(List coordinates) { + this.coordinates = coordinates; + } + + public List coordinates; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Mapbox.getInstance(this, getString(R.string.access_token)); setContentView(R.layout.activity_main); - - - mRequestUpdatesButton = (Button) findViewById(R.id.request_updates_button); - mRemoveUpdatesButton = (Button) findViewById(R.id.remove_updates_button); - mLocationUpdatesResultView = (TextView) findViewById(R.id.location_updates_result); - - + Bundle extras = getIntent().getExtras(); mMainFrame = (FrameLayout) findViewById(R.id.main_frame); mMainNav = (BottomNavigationView) findViewById(R.id.main_nav); + isTutor = (boolean) extras.get("is_tutor"); + + if (!isTutor) { + mMainNav.findViewById(R.id.nav_profile).setVisibility(View.GONE); + } mapFragment = new MapFragment(); notificationFragment = new NotificationFragment(); profileFragment = new ProfileFragment(); // Default frag here - //setFragment(mapFragment); - //mMainNav.setSelectedItemId(R.id.nav_map); + setFragment(mapFragment); + mMainNav.setSelectedItemId(R.id.nav_map); + /* code below is resposible for changing colours of tabs in main tab menu */ mMainNav.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { @Override public boolean onNavigationItemSelected(@NonNull MenuItem item) { switch (item.getItemId()) { case R.id.nav_map: - mMainNav.setItemBackgroundResource(R.color.colorPrimary); setFragment(mapFragment); return true; case R.id.nav_notif: - mMainNav.setItemBackgroundResource(R.color.colorAccent); setFragment(notificationFragment); return true; case R.id.nav_profile: - mMainNav.setItemBackgroundResource(R.color.colorPrimaryDark); setFragment(profileFragment); return true; default: @@ -139,293 +121,129 @@ public class MainActivity extends AppCompatActivity implements GoogleApiClient. // Logout button final FloatingActionButton button = findViewById(R.id.logoutButton); - button.setOnClickListener(new View.OnClickListener(){ + button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { - SharedPreferences preferences = getSharedPreferences("fmtPrefs",Context.MODE_PRIVATE); + SharedPreferences preferences = getSharedPreferences("fmtPrefs", Context.MODE_PRIVATE); SharedPreferences.Editor editor = preferences.edit(); editor.clear().commit(); Intent i = getBaseContext().getPackageManager() - .getLaunchIntentForPackage( getBaseContext().getPackageName() ); + .getLaunchIntentForPackage(getBaseContext().getPackageName()); i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(i); finish(); } }); + geocoder = new Geocoder(this, Locale.getDefault()); + mPref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); + medit = mPref.edit(); - // Check if the user revoked runtime permissions. - if (!checkPermissions()) { - requestPermissions(); + if (boolean_permission) { + + if (mPref.getString("service", "").matches("")) { + medit.putString("service", "service").commit(); + + Intent intent = new Intent(getApplicationContext(), GoogleService.class); + startService(intent); + + } else { + Toast.makeText(getApplicationContext(), "Service is already running", Toast.LENGTH_SHORT).show(); + } + } else { + Toast.makeText(getApplicationContext(), "Please enable the gps", Toast.LENGTH_SHORT).show(); } - buildGoogleApiClient(); - } - private void setFragment(Fragment fragment) { FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction(); fragmentTransaction.replace(R.id.main_frame, fragment); fragmentTransaction.commit(); } - - @Override - protected void onStart() { - super.onStart(); - PreferenceManager.getDefaultSharedPreferences(this) - .registerOnSharedPreferenceChangeListener(this); - } - - @Override protected void onResume() { super.onResume(); - updateButtonsState(LocationRequestHelper.getRequesting(this)); - mLocationUpdatesResultView.setText(LocationResultHelper.getSavedLocationResult(this)); + registerReceiver(broadcastReceiver, new IntentFilter(GoogleService.str_receiver)); + } @Override - protected void onStop() { - PreferenceManager.getDefaultSharedPreferences(this) - .unregisterOnSharedPreferenceChangeListener(this); - super.onStop(); + protected void onPause() { + super.onPause(); + unregisterReceiver(broadcastReceiver); } - /** - * Sets up the location request. Android has two location request settings: - * {@code ACCESS_COARSE_LOCATION} and {@code ACCESS_FINE_LOCATION}. These settings control - * the accuracy of the current location. This sample uses ACCESS_FINE_LOCATION, as defined in - * the AndroidManifest.xml. - *

- * When the ACCESS_FINE_LOCATION setting is specified, combined with a fast update - * interval (5 seconds), the Fused Location Provider API returns location updates that are - * accurate to within a few feet. - *

- * These settings are appropriate for mapping applications that show real-time location - * updates. - */ - private void createLocationRequest() { - mLocationRequest = new LocationRequest(); + private void fn_permission() { + if ((ContextCompat.checkSelfPermission(getApplicationContext(), android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED)) { - mLocationRequest.setInterval(UPDATE_INTERVAL); + if ((ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, android.Manifest.permission.ACCESS_FINE_LOCATION))) { - // Sets the fastest rate for active location updates. This interval is exact, and your - // application will never receive updates faster than this value. - mLocationRequest.setFastestInterval(FASTEST_UPDATE_INTERVAL); - mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); - // Sets the maximum time when batched location updates are delivered. Updates may be - // delivered sooner than this interval. - mLocationRequest.setMaxWaitTime(MAX_WAIT_TIME); - } - - /** - * Builds {@link GoogleApiClient}, enabling automatic lifecycle management using - * {@link GoogleApiClient.Builder#enableAutoManage(android.support.v4.app.FragmentActivity, - * int, GoogleApiClient.OnConnectionFailedListener)}. I.e., GoogleApiClient connects in - * {@link AppCompatActivity#onStart}, or if onStart() has already happened, it connects - * immediately, and disconnects automatically in {@link AppCompatActivity#onStop}. - */ - private void buildGoogleApiClient() { - if (mGoogleApiClient != null) { - return; - } - mGoogleApiClient = new GoogleApiClient.Builder(this) - .addConnectionCallbacks(this) - .enableAutoManage(this, this) - .addApi(LocationServices.API) - .build(); - createLocationRequest(); - } - - @Override - public void onConnected(@Nullable Bundle bundle) { - Log.i(TAG, "GoogleApiClient connected"); - } - - private PendingIntent getPendingIntent() { - Intent intent = new Intent(this, LocationUpdatesBroadcastReceiver.class); - intent.setAction(LocationUpdatesBroadcastReceiver.ACTION_PROCESS_UPDATES); - return PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); - } - - @Override - public void onConnectionSuspended(int i) { - final String text = "Connection suspended"; - Log.w(TAG, text + ": Error code: " + i); - showSnackbar("Connection suspended"); - } - - @Override - public void onConnectionFailed(@NonNull ConnectionResult connectionResult) { - final String text = "Exception while connecting to Google Play services"; - Log.w(TAG, text + ": " + connectionResult.getErrorMessage()); - showSnackbar(text); - } - - /** - * Shows a {@link Snackbar} using {@code text}. - * - * @param text The Snackbar text. - */ - private void showSnackbar(final String text) { - View container = findViewById(R.id.activity_main); - if (container != null) { - Snackbar.make(container, text, Snackbar.LENGTH_LONG).show(); - } - } - - /** - * Return the current state of the permissions needed. - */ - private boolean checkPermissions() { - int permissionState = ActivityCompat.checkSelfPermission(this, - Manifest.permission.ACCESS_FINE_LOCATION); - return permissionState == PackageManager.PERMISSION_GRANTED; - } - - private void requestPermissions() { - boolean shouldProvideRationale = - ActivityCompat.shouldShowRequestPermissionRationale(this, - Manifest.permission.ACCESS_FINE_LOCATION); - - // Provide an additional rationale to the user. This would happen if the user denied the - // request previously, but didn't check the "Don't ask again" checkbox. - if (shouldProvideRationale) { - Log.i(TAG, "Displaying permission rationale to provide additional context."); - Snackbar.make( - findViewById(R.id.activity_main), - R.string.permission_rationale, - Snackbar.LENGTH_INDEFINITE) - .setAction(R.string.ok, new View.OnClickListener() { - @Override - public void onClick(View view) { - // Request permission - ActivityCompat.requestPermissions(MainActivity.this, - new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, - REQUEST_PERMISSIONS_REQUEST_CODE); - } - }) - .show(); - } else { - Log.i(TAG, "Requesting permission"); - // Request permission. It's possible this can be auto answered if device policy - // sets the permission in a given state or the user denied the permission - // previously and checked "Never ask again". - ActivityCompat.requestPermissions(MainActivity.this, - new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, - REQUEST_PERMISSIONS_REQUEST_CODE); - } - } - - /** - * Callback received when a permissions request has been completed. - */ - @Override - public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, - @NonNull int[] grantResults) { - Log.i(TAG, "onRequestPermissionResult"); - if (requestCode == REQUEST_PERMISSIONS_REQUEST_CODE) { - if (grantResults.length <= 0) { - // If user interaction was interrupted, the permission request is cancelled and you - // receive empty arrays. - Log.i(TAG, "User interaction was cancelled."); - } else if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { - // Permission was granted. Kick off the process of building and connecting - // GoogleApiClient. - buildGoogleApiClient(); } else { - // Permission denied. + ActivityCompat.requestPermissions(MainActivity.this, new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION - // Notify the user via a SnackBar that they have rejected a core permission for the - // app, which makes the Activity useless. In a real app, core permissions would - // typically be best requested during a welcome-screen flow. + }, + REQUEST_PERMISSIONS); - // Additionally, it is important to remember that a permission might have been - // rejected without asking the user for permission (device policy or "Never ask - // again" prompts). Therefore, a user interface affordance is typically implemented - // when permissions are denied. Otherwise, your app could appear unresponsive to - // touches or interactions which have required permissions. - Snackbar.make( - findViewById(R.id.activity_main), - R.string.permission_denied_explanation, - Snackbar.LENGTH_INDEFINITE) - .setAction(R.string.settings, new View.OnClickListener() { - @Override - public void onClick(View view) { - // Build intent that displays the App settings screen. - Intent intent = new Intent(); - intent.setAction( - Settings.ACTION_APPLICATION_DETAILS_SETTINGS); - Uri uri = Uri.fromParts("package", - BuildConfig.APPLICATION_ID, null); - intent.setData(uri); - intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - startActivity(intent); - } - }) - .show(); + } + } else { + boolean_permission = true; + } + } + + @Override + public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + + switch (requestCode) { + case REQUEST_PERMISSIONS: { + if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { + boolean_permission = true; + + } else { + Toast.makeText(getApplicationContext(), "Please allow the permission", Toast.LENGTH_LONG).show(); + + } } } + } + + private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + + latitude = Double.valueOf(intent.getStringExtra("latutide")); + longitude = Double.valueOf(intent.getStringExtra("longitude")); + + List

addresses = null; + + try { + addresses = geocoder.getFromLocation(latitude, longitude, 1); + String cityName = addresses.get(0).getAddressLine(0); + String stateName = addresses.get(0).getAddressLine(1); + String countryName = addresses.get(0).getAddressLine(2); + + tv_area.setText(addresses.get(0).getAdminArea()); + tv_locality.setText(stateName); + tv_address.setText(countryName); + + + } catch (IOException e1) { + e1.printStackTrace(); + } + + + tv_latitude.setText(latitude + ""); + tv_longitude.setText(longitude + ""); + tv_address.getText(); - try { - Log.i(TAG, "Starting location updates"); - LocationRequestHelper.setRequesting(this, true); - LocationServices.FusedLocationApi.requestLocationUpdates( - mGoogleApiClient, mLocationRequest, getPendingIntent()); - } catch (SecurityException e) { - LocationRequestHelper.setRequesting(this, false); - e.printStackTrace(); } - } - - @Override - public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String s) { - if (s.equals(LocationResultHelper.KEY_LOCATION_UPDATES_RESULT)) { - Log.e("Service",LocationResultHelper.getSavedLocationResult(this)); - } else if (s.equals(LocationRequestHelper.KEY_LOCATION_UPDATES_REQUESTED)) { - updateButtonsState(LocationRequestHelper.getRequesting(this)); - } - } - - /** - * Handles the Request Updates button and requests start of location updates. - */ - public void requestLocationUpdates(View view) { - try { - Log.i(TAG, "Starting location updates"); - LocationRequestHelper.setRequesting(this, true); - LocationServices.FusedLocationApi.requestLocationUpdates( - mGoogleApiClient, mLocationRequest, getPendingIntent()); - } catch (SecurityException e) { - LocationRequestHelper.setRequesting(this, false); - e.printStackTrace(); - } - } - - /** - * Handles the Remove Updates button, and requests removal of location updates. - */ - public void removeLocationUpdates(View view) { - Log.i(TAG, "Removing location updates"); - LocationRequestHelper.setRequesting(this, false); - LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, - getPendingIntent()); - } - - /** - * Ensures that only one button is enabled at any time. The Start Updates button is enabled - * if the user is not requesting location updates. The Stop Updates button is enabled if the - * user is requesting location updates. - */ - private void updateButtonsState(boolean requestingLocationUpdates) { - - } + }; } diff --git a/app/src/main/java/com/uam/wmi/findmytutor/service/GoogleService.java b/app/src/main/java/com/uam/wmi/findmytutor/service/GoogleService.java new file mode 100644 index 0000000..dd9f0b6 --- /dev/null +++ b/app/src/main/java/com/uam/wmi/findmytutor/service/GoogleService.java @@ -0,0 +1,158 @@ +package com.uam.wmi.findmytutor.service; + +import android.Manifest; +import android.app.Service; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Bundle; +import android.os.Handler; +import android.os.IBinder; +import android.support.annotation.Nullable; +import android.support.v4.app.ActivityCompat; +import android.util.Log; + +import java.util.Timer; +import java.util.TimerTask; + +/** + * Created by deepshikha on 24/11/16. + */ + +public class GoogleService extends Service implements LocationListener { + + boolean isGPSEnable = false; + boolean isNetworkEnable = false; + double latitude, longitude; + LocationManager locationManager; + Location location; + private Handler mHandler = new Handler(); + private Timer mTimer = null; + long notify_interval = 5000; + public static String str_receiver = "servicetutorial.service.receiver"; + Intent intent; + + + public GoogleService() { + + } + + @Nullable + @Override + public IBinder onBind(Intent intent) { + return null; + } + + @Override + public void onCreate() { + super.onCreate(); + + mTimer = new Timer(); + mTimer.schedule(new TimerTaskToGetLocation(), 5, notify_interval); + intent = new Intent(str_receiver); + } + + @Override + public void onLocationChanged(Location location) { + + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + + } + + @Override + public void onProviderEnabled(String provider) { + + } + + @Override + public void onProviderDisabled(String provider) { + + } + + private void fn_getlocation() { + locationManager = (LocationManager) getApplicationContext().getSystemService(LOCATION_SERVICE); + isGPSEnable = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER); + isNetworkEnable = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER); + + if (!isGPSEnable && !isNetworkEnable) { + + } else { + + if (isNetworkEnable) { + location = null; + if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + // TODO: Consider calling + // ActivityCompat#requestPermissions + // here to request the missing permissions, and then overriding + // public void onRequestPermissionsResult(int requestCode, String[] permissions, + // int[] grantResults) + // to handle the case where the user grants the permission. See the documentation + // for ActivityCompat#requestPermissions for more details. + return; + } + locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1000, 0, this); + if (locationManager!=null){ + location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); + if (location!=null){ + + Log.e("latitude",location.getLatitude()+""); + Log.e("longitude",location.getLongitude()+""); + + latitude = location.getLatitude(); + longitude = location.getLongitude(); + fn_update(location); + } + } + + } + + + if (isGPSEnable){ + location = null; + locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,1000,0,this); + if (locationManager!=null){ + location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + if (location!=null){ + Log.e("latitude",location.getLatitude()+""); + Log.e("longitude",location.getLongitude()+""); + latitude = location.getLatitude(); + longitude = location.getLongitude(); + fn_update(location); + } + } + } + + + } + + } + + private class TimerTaskToGetLocation extends TimerTask{ + @Override + public void run() { + + mHandler.post(new Runnable() { + @Override + public void run() { + fn_getlocation(); + } + }); + + } + } + + private void fn_update(Location location){ + + intent.putExtra("latutide",location.getLatitude()+""); + intent.putExtra("longitude",location.getLongitude()+""); + sendBroadcast(intent); + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/uam/wmi/findmytutor/service/LocationService.java b/app/src/main/java/com/uam/wmi/findmytutor/service/LocationService.java deleted file mode 100644 index 566ae34..0000000 --- a/app/src/main/java/com/uam/wmi/findmytutor/service/LocationService.java +++ /dev/null @@ -1,397 +0,0 @@ -package com.uam.wmi.findmytutor.service; - -import android.annotation.SuppressLint; -import android.app.Service; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.location.Criteria; -import android.location.GpsStatus; -import android.location.Location; -import android.location.LocationListener; -import android.location.LocationManager; -import android.location.LocationProvider; -import android.os.BatteryManager; -import android.os.Binder; -import android.os.Bundle; -import android.os.IBinder; -import android.os.SystemClock; -import android.support.v4.content.LocalBroadcastManager; -import android.util.Log; - -import java.io.FileWriter; -import java.io.IOException; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Date; - -import static android.content.ContentValues.TAG; - -public class LocationService extends Service implements LocationListener, GpsStatus.Listener { - public static final String LOG_TAG = LocationService.class.getSimpleName(); - - private final LocationServiceBinder binder = new LocationServiceBinder(); - boolean isLocationManagerUpdatingLocation; - - - - ArrayList locationList; - - ArrayList oldLocationList; - ArrayList noAccuracyLocationList; - ArrayList inaccurateLocationList; - - - boolean isLogging; - - float currentSpeed = 0.0f; // meters/second - long runStartTimeInMillis; - - ArrayList batteryLevelArray; - ArrayList batteryLevelScaledArray; - int batteryScale; - int gpsCount; - - - public LocationService() { - - } - - @Override - public void onCreate() { - isLocationManagerUpdatingLocation = false; - locationList = new ArrayList<>(); - noAccuracyLocationList = new ArrayList<>(); - oldLocationList = new ArrayList<>(); - inaccurateLocationList = new ArrayList<>(); - - isLogging = false; - - batteryLevelArray = new ArrayList<>(); - batteryLevelScaledArray = new ArrayList<>(); - registerReceiver(this.batteryInfoReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED)); - } - - - - @Override - public int onStartCommand(Intent i, int flags, int startId) { - super.onStartCommand(i, flags, startId); - return Service.START_STICKY; - } - - - @Override - public IBinder onBind(Intent intent) { - return binder; - } - - - @Override - public void onRebind(Intent intent) { - Log.d(LOG_TAG, "onRebind "); - } - - @Override - public boolean onUnbind(Intent intent) { - Log.d(LOG_TAG, "onUnbind "); - - return true; - } - - @Override - public void onDestroy() { - Log.d(LOG_TAG, "onDestroy "); - - - } - - - //This is where we detect the app is being killed, thus stop service. - @Override - public void onTaskRemoved(Intent rootIntent) { - Log.d(LOG_TAG, "onTaskRemoved "); - this.stopUpdatingLocation(); - - stopSelf(); - } - - - - - /** - * Binder class - * - * @author Takamitsu Mizutori - * - */ - public class LocationServiceBinder extends Binder { - public LocationService getService() { - return LocationService.this; - } - } - - - - /* LocationListener implemenation */ - @Override - public void onProviderDisabled(String provider) { - if (provider.equals(LocationManager.GPS_PROVIDER)) { - notifyLocationProviderStatusUpdated(false); - } - - } - - @Override - public void onProviderEnabled(String provider) { - if (provider.equals(LocationManager.GPS_PROVIDER)) { - notifyLocationProviderStatusUpdated(true); - } - } - - @Override - public void onStatusChanged(String provider, int status, Bundle extras) { - if (provider.equals(LocationManager.GPS_PROVIDER)) { - if (status == LocationProvider.OUT_OF_SERVICE) { - notifyLocationProviderStatusUpdated(false); - } else { - notifyLocationProviderStatusUpdated(true); - } - } - } - - /* GpsStatus.Listener implementation */ - public void onGpsStatusChanged(int event) { - - - } - - private void notifyLocationProviderStatusUpdated(boolean isLocationProviderAvailable) { - //Broadcast location provider status change here - } - - public void startLogging(){ - isLogging = true; - } - - public void stopLogging(){ - if (locationList.size() > 1 && batteryLevelArray.size() > 1){ - long currentTimeInMillis = (long)(SystemClock.elapsedRealtimeNanos() / 1000000); - long elapsedTimeInSeconds = (currentTimeInMillis - runStartTimeInMillis) / 1000; - float totalDistanceInMeters = 0; - for(int i = 0; i < locationList.size() - 1; i++){ - totalDistanceInMeters += locationList.get(i).distanceTo(locationList.get(i + 1)); - } - int batteryLevelStart = batteryLevelArray.get(0).intValue(); - int batteryLevelEnd = batteryLevelArray.get(batteryLevelArray.size() - 1).intValue(); - - float batteryLevelScaledStart = batteryLevelScaledArray.get(0).floatValue(); - float batteryLevelScaledEnd = batteryLevelScaledArray.get(batteryLevelScaledArray.size() - 1).floatValue(); - - saveLog(elapsedTimeInSeconds, totalDistanceInMeters, gpsCount, batteryLevelStart, batteryLevelEnd, batteryLevelScaledStart, batteryLevelScaledEnd); - } - isLogging = false; - } - - - - public void startUpdatingLocation() { - if(this.isLocationManagerUpdatingLocation == false){ - isLocationManagerUpdatingLocation = true; - runStartTimeInMillis = (long)(SystemClock.elapsedRealtimeNanos() / 1000000); - - - locationList.clear(); - - oldLocationList.clear(); - noAccuracyLocationList.clear(); - inaccurateLocationList.clear(); - - LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE); - - //Exception thrown when GPS or Network provider were not available on the user's device. - try { - Criteria criteria = new Criteria(); - criteria.setAccuracy(Criteria.ACCURACY_FINE); //setAccuracyは内部では、https://stackoverflow.com/a/17874592/1709287の用にHorizontalAccuracyの設定に変換されている。 - criteria.setPowerRequirement(Criteria.POWER_HIGH); - criteria.setAltitudeRequired(false); - criteria.setSpeedRequired(true); - criteria.setCostAllowed(true); - criteria.setBearingRequired(false); - - //API level 9 and up - criteria.setHorizontalAccuracy(Criteria.ACCURACY_HIGH); - criteria.setVerticalAccuracy(Criteria.ACCURACY_HIGH); - //criteria.setBearingAccuracy(Criteria.ACCURACY_HIGH); - //criteria.setSpeedAccuracy(Criteria.ACCURACY_HIGH); - - Integer gpsFreqInMillis = 5000; - Integer gpsFreqInDistance = 5; // in meters - - locationManager.addGpsStatusListener(this); - - locationManager.requestLocationUpdates(gpsFreqInMillis, gpsFreqInDistance, criteria, this, null); - - /* Battery Consumption Measurement */ - gpsCount = 0; - batteryLevelArray.clear(); - batteryLevelScaledArray.clear(); - - } catch (IllegalArgumentException e) { - Log.e(LOG_TAG, e.getLocalizedMessage()); - } catch (SecurityException e) { - Log.e(LOG_TAG, e.getLocalizedMessage()); - } catch (RuntimeException e) { - Log.e(LOG_TAG, e.getLocalizedMessage()); - } - } - } - - - public void stopUpdatingLocation(){ - if(this.isLocationManagerUpdatingLocation == true){ - LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE); - locationManager.removeUpdates(this); - isLocationManagerUpdatingLocation = false; - } - } - - @Override - public void onLocationChanged(final Location newLocation) { - Log.d(TAG, "(" + newLocation.getLatitude() + "," + newLocation.getLongitude() + ")"); - - gpsCount++; - - if(isLogging){ - //locationList.add(newLocation); - filterAndAddLocation(newLocation); - } - - Intent intent = new Intent("LocationUpdated"); - intent.putExtra("location", newLocation); - - LocalBroadcastManager.getInstance(this.getApplication()).sendBroadcast(intent); - } - - @SuppressLint("NewApi") - private long getLocationAge(Location newLocation){ - long locationAge; - if(android.os.Build.VERSION.SDK_INT >= 17) { - long currentTimeInMilli = (long)(SystemClock.elapsedRealtimeNanos() / 1000000); - long locationTimeInMilli = (long)(newLocation.getElapsedRealtimeNanos() / 1000000); - locationAge = currentTimeInMilli - locationTimeInMilli; - }else{ - locationAge = System.currentTimeMillis() - newLocation.getTime(); - } - return locationAge; - } - - - private boolean filterAndAddLocation(Location location){ - - long age = getLocationAge(location); - - if(age > 5 * 1000){ //more than 5 seconds - Log.d(TAG, "Location is old"); - oldLocationList.add(location); - return false; - } - - if(location.getAccuracy() <= 0){ - Log.d(TAG, "Latitidue and longitude values are invalid."); - noAccuracyLocationList.add(location); - return false; - } - - //setAccuracy(newLocation.getAccuracy()); - float horizontalAccuracy = location.getAccuracy(); - if(horizontalAccuracy > 10){ //10meter filter - Log.d(TAG, "Accuracy is too low."); - inaccurateLocationList.add(location); - return false; - } - - - /* Kalman Filter */ - float Qvalue; - - long locationTimeInMillis = (long)(location.getElapsedRealtimeNanos() / 1000000); - long elapsedTimeInMillis = locationTimeInMillis - runStartTimeInMillis; - - if(currentSpeed == 0.0f){ - Qvalue = 3.0f; //3 meters per second - }else{ - Qvalue = currentSpeed; // meters per second - } - - - - Location predictedLocation = new Location("");//provider name is unecessary - float predictedDeltaInMeters = predictedLocation.distanceTo(location); - - - /* Notifiy predicted location to UI */ - Intent intent = new Intent("PredictLocation"); - intent.putExtra("location", predictedLocation); - LocalBroadcastManager.getInstance(this.getApplication()).sendBroadcast(intent); - - Log.d(TAG, "Location quality is good enough."); - currentSpeed = location.getSpeed(); - locationList.add(location); - - - return true; - } - - - - /* Battery Consumption */ - private BroadcastReceiver batteryInfoReceiver = new BroadcastReceiver(){ - @Override - public void onReceive(Context ctxt, Intent intent) { - int batteryLevel = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0); - int scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1); - - float batteryLevelScaled = batteryLevel / (float)scale; - - - - batteryLevelArray.add(Integer.valueOf(batteryLevel)); - batteryLevelScaledArray.add(Float.valueOf(batteryLevelScaled)); - batteryScale = scale; - } - }; - - /* Data Logging */ - public synchronized void saveLog(long timeInSeconds, double distanceInMeters, int gpsCount, int batteryLevelStart, int batteryLevelEnd, float batteryLevelScaledStart, float batteryLevelScaledEnd) { - SimpleDateFormat fileNameDateTimeFormat = new SimpleDateFormat("yyyy_MMdd_HHmm"); - String filePath = this.getExternalFilesDir(null).getAbsolutePath() + "/" - + fileNameDateTimeFormat.format(new Date()) + "_battery" + ".csv"; - - Log.d(TAG, "saving to " + filePath); - - FileWriter fileWriter = null; - try { - fileWriter = new FileWriter(filePath, false); - fileWriter.append("Time,Distance,GPSCount,BatteryLevelStart,BatteryLevelEnd,BatteryLevelStart(/" + batteryScale + ")," + "BatteryLevelEnd(/" + batteryScale + ")" + "\n"); - String record = "" + timeInSeconds + ',' + distanceInMeters + ',' + gpsCount + ',' + batteryLevelStart + ',' + batteryLevelEnd + ',' + batteryLevelScaledStart + ',' + batteryLevelScaledEnd + '\n'; - fileWriter.append(record); - } catch (Exception e) { - e.printStackTrace(); - } finally { - if (fileWriter != null) { - try { - fileWriter.close(); - } catch (IOException ioe) { - ioe.printStackTrace(); - } - } - } - } - - - -} - - diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 37fcb88..4c9470a 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -1,17 +1,16 @@ + android:layout_height="wrap_content"> + + + - - - - -