package com.akhgupta.easylocation; import android.Manifest; import android.app.Activity; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager; import android.location.Location; import android.location.LocationManager; import android.provider.Settings; import android.support.v4.app.ActivityCompat; import android.support.v4.content.ContextCompat; import android.support.v4.content.LocalBroadcastManager; import android.support.v7.app.AlertDialog; import android.text.TextUtils; import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.GoogleApiAvailability; import com.google.android.gms.location.LocationRequest; import static com.akhgupta.easylocation.AppConstants.CONTINUOUS_LOCATION_UPDATES; import static com.akhgupta.easylocation.AppConstants.SINGLE_FIX; class EasyLocationDelegate { private static final int PERMISSIONS_REQUEST = 100; private static final int ENABLE_LOCATION_SERVICES_REQUEST = 101; private static final int GOOGLE_PLAY_SERVICES_ERROR_DIALOG = 102; private final Activity activity; private final EasyLocationListener easyLocationListener; private final LocationBroadcastReceiver locationReceiver; private LocationManager mLocationManager; private int mLocationFetchMode; private LocationRequest mLocationRequest; private GoogleApiAvailability googleApiAvailability; private EasyLocationRequest easyLocationRequest; EasyLocationDelegate(Activity activity, EasyLocationListener easyLocationListener) { this.activity = activity; this.easyLocationListener = easyLocationListener; locationReceiver = new LocationBroadcastReceiver(easyLocationListener); } private boolean isLocationEnabled() { return isGPSLocationEnabled() || isNetworkLocationEnabled(); } private boolean isGPSLocationEnabled() { return mLocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER); } private boolean isNetworkLocationEnabled() { return mLocationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER); } private void openLocationSettings() { Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS); activity.startActivityForResult(intent, ENABLE_LOCATION_SERVICES_REQUEST); } void stopLocationUpdates() { Intent intent = new Intent(activity, LocationBgService.class); intent.setAction(AppConstants.ACTION_LOCATION_FETCH_STOP); activity.startService(intent); } private void isProperRequest(EasyLocationRequest easyLocationRequest) { if (easyLocationRequest == null) throw new IllegalStateException("easyLocationRequest can't be null"); if (easyLocationRequest.locationRequest == null) throw new IllegalStateException("locationRequest can't be null"); this.easyLocationRequest = easyLocationRequest; } private void startLocationBGService(LocationRequest locationRequest, long fallBackToLastLocationTime) { if (!isLocationEnabled()) showLocationServicesRequireDialog(); else { Intent intent = new Intent(activity, LocationBgService.class); intent.setAction(AppConstants.ACTION_LOCATION_FETCH_START); intent.putExtra(IntentKey.LOCATION_REQUEST, locationRequest); intent.putExtra(IntentKey.LOCATION_FETCH_MODE, mLocationFetchMode); intent.putExtra(IntentKey.FALLBACK_TO_LAST_LOCATION_TIME, fallBackToLastLocationTime); activity.startService(intent); } } private boolean hasLocationPermission() { return ContextCompat.checkSelfPermission(activity, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED; } private void showPermissionRequireDialog() { String title = TextUtils.isEmpty(easyLocationRequest.locationPermissionDialogTitle) ? activity.getString(R.string.location_permission_dialog_title) : easyLocationRequest.locationPermissionDialogTitle; String message = TextUtils.isEmpty(easyLocationRequest.locationPermissionDialogMessage) ? activity.getString(R.string.location_permission_dialog_message) : easyLocationRequest.locationPermissionDialogMessage; String negativeButtonTitle = TextUtils.isEmpty(easyLocationRequest.locationPermissionDialogNegativeButtonText) ? activity.getString(android.R.string.cancel) : easyLocationRequest.locationPermissionDialogNegativeButtonText; String positiveButtonTitle = TextUtils.isEmpty(easyLocationRequest.locationPermissionDialogPositiveButtonText) ? activity.getString(android.R.string.ok) : easyLocationRequest.locationPermissionDialogPositiveButtonText; new AlertDialog.Builder(activity) .setCancelable(true) .setTitle(title) .setMessage(message) .setNegativeButton(negativeButtonTitle, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { easyLocationListener.onLocationPermissionDenied(); } }) .setPositiveButton(positiveButtonTitle, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { requestPermission(); } }).create().show(); } private void showLocationServicesRequireDialog() { String title = TextUtils.isEmpty(easyLocationRequest.locationSettingsDialogTitle) ? activity.getString(R.string.location_services_off) : easyLocationRequest.locationSettingsDialogTitle; String message = TextUtils.isEmpty(easyLocationRequest.locationSettingsDialogMessage) ? activity.getString(R.string.open_location_settings) : easyLocationRequest.locationSettingsDialogMessage; String negativeButtonText = TextUtils.isEmpty(easyLocationRequest.locationSettingsDialogNegativeButtonText) ? activity.getString(android.R.string.cancel) : easyLocationRequest.locationSettingsDialogNegativeButtonText; String positiveButtonText = TextUtils.isEmpty(easyLocationRequest.locationSettingsDialogPositiveButtonText) ? activity.getString(android.R.string.ok) : easyLocationRequest.locationSettingsDialogPositiveButtonText; new AlertDialog.Builder(activity) .setCancelable(true) .setTitle(title) .setMessage(message) .setNegativeButton(negativeButtonText, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { easyLocationListener.onLocationProviderDisabled(); } }) .setPositiveButton(positiveButtonText, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { openLocationSettings(); } }) .create().show(); } private void requestPermission() { ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, PERMISSIONS_REQUEST); } private void requestLocation(LocationRequest locationRequest, int locationMode) { if (isGoogleServiceAvailable()) { mLocationFetchMode = locationMode; mLocationRequest = locationRequest; checkForPermissionAndRequestLocation(locationRequest); } else showGooglePlayServicesErrorDialog(); } private void checkForPermissionAndRequestLocation(LocationRequest locationRequest) { if (!hasLocationPermission()) { if (ActivityCompat.shouldShowRequestPermissionRationale(activity, android.Manifest.permission.ACCESS_FINE_LOCATION)) showPermissionRequireDialog(); else requestPermission(); } else startLocationBGService(locationRequest,easyLocationRequest.fallBackToLastLocationTime); } private void unregisterLocationBroadcastReceiver() { LocalBroadcastManager.getInstance(activity).unregisterReceiver(locationReceiver); } private void registerLocationBroadcastReceiver() { IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(AppConstants.INTENT_LOCATION_RECEIVED); intentFilter.addAction(AppConstants.INTENT_NO_LOCATION_RECEIVED); LocalBroadcastManager.getInstance(activity).registerReceiver(locationReceiver, intentFilter); } private boolean isGoogleServiceAvailable() { return googleApiAvailability.isGooglePlayServicesAvailable(activity) == ConnectionResult.SUCCESS; } private void showGooglePlayServicesErrorDialog() { int errorCode = googleApiAvailability.isGooglePlayServicesAvailable(activity); if (googleApiAvailability.isUserResolvableError(errorCode)) googleApiAvailability.getErrorDialog(activity, errorCode, GOOGLE_PLAY_SERVICES_ERROR_DIALOG).show(); } void onCreate() { mLocationManager = (LocationManager) activity.getSystemService(Context.LOCATION_SERVICE); googleApiAvailability = GoogleApiAvailability.getInstance(); registerLocationBroadcastReceiver(); } void onActivityResult(int requestCode) { switch (requestCode) { case ENABLE_LOCATION_SERVICES_REQUEST: if (isLocationEnabled()) { requestLocation(mLocationRequest, mLocationFetchMode); easyLocationListener.onLocationProviderEnabled(); } else easyLocationListener.onLocationProviderDisabled(); break; } } void onRequestPermissionsResult(int requestCode, int[] grantResults) { switch (requestCode) { case PERMISSIONS_REQUEST: if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { requestLocation(mLocationRequest, mLocationFetchMode); easyLocationListener.onLocationPermissionGranted(); } else easyLocationListener.onLocationPermissionDenied(); break; } } void onDestroy() { stopLocationUpdates(); unregisterLocationBroadcastReceiver(); } Location getLastKnownLocation() { return PreferenceUtil.getInstance(activity).getLastKnownLocation(); } void requestLocationUpdates(EasyLocationRequest easyLocationRequest) { isProperRequest(easyLocationRequest); requestLocation(easyLocationRequest.locationRequest, CONTINUOUS_LOCATION_UPDATES); } void requestSingleLocationFix(EasyLocationRequest easyLocationRequest) { isProperRequest(easyLocationRequest); requestLocation(easyLocationRequest.locationRequest, SINGLE_FIX); } }