Show User Location on Map Failed with API Client Connection Error - android

I want to show the user's location on a map whenever a toggle button is pressed. I have written the code like below and it works only to show the map but not the user's location and sometimes throws error like:
java.lang.IllegalStateException: GoogleApiClient is not connected yet.
on this line: LocationServices.FusedLocationApi.requestLocationUpdates(apiClient, locationRequest, this);
I am able to get the location in logcat but can't show on map. Here's the fragment code:
public class HomeFragment extends BaseFragment implements OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, com.google.android.gms.location.LocationListener {
private static final String TAG = HomeFragment.class.getSimpleName();
private Toolbar toolbar;
private TextView driverStatusTV;
public static MaterialAnimatedSwitch statusSwitch;
public static GoogleApiClient apiClient;
public static Location mLastLocation;
public static LocationRequest locationRequest;
public GoogleMap mGmap;
public static Marker currentMarker;
public static double latitude = 0f, longitude = 0f;
public static final int UPDATE_INTERVAL = 15000;
public static final int FASTEST_INTERVAL = 8000;
public static final int DISPLACEMENT = 10;
public static final int PLAY_SERVICES_REQ_CODE = 9009;
public static final int PLAY_SERVICES_RESOLUTION_REQ_CODE = 9090;
private SupportMapFragment mapFragment;
public HomeFragment() {
// Required empty public constructor
}
private void initViews(View view) {
toolbar = view.findViewById(R.id.toolbar);
driverStatusTV = view.findViewById(R.id.driverStatusTV);
statusSwitch = view.findViewById(R.id.statusSwitch);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_home, container, false);
initViews(view);
((AppCompatActivity) getActivity()).setSupportActionBar(toolbar);
mapFragment = (SupportMapFragment) this.getChildFragmentManager().findFragmentById(R.id.mapFragment);
mapFragment.getMapAsync(this);
setUpLocation();
statusSwitch.setOnCheckedChangeListener(new MaterialAnimatedSwitch.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(boolean b) {
if (b){
Snackbar.make(getActivity().findViewById(android.R.id.content), "You are Now Online", Snackbar.LENGTH_LONG).show();
startLocationListener();
displayLocation();
driverStatusTV.setText("ONLINE");
} else {
Snackbar.make(getActivity().findViewById(android.R.id.content), "You are Now Offline", Snackbar.LENGTH_LONG).show();
stopLocationListener();
driverStatusTV.setText("OFFLINE");
//currentMarker.remove();
}
}
});
return view;
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case AppConstants.LOC_PERM_CODE:
for (int gr : grantResults) {
if (gr == PackageManager.PERMISSION_GRANTED) {
if (checkPlayServices()) {
makeLocationRequest();
initAPIClient();
if (statusSwitch.isChecked()) {
displayLocation();
}
} else {
Snackbar.make(getActivity().findViewById(android.R.id.content), "Google Play Services Not Supported on Your Device", Snackbar.LENGTH_LONG).show();
}
} else {
getActivity().finish();
getActivity().moveTaskToBack(true);
}
}
break;
}
}
public void startLocationListener() {
if (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
|| ContextCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, AppConstants.LOC_PERM_CODE);
} else {
initAPIClient();
apiClient.connect();
LocationServices.FusedLocationApi.requestLocationUpdates(apiClient, locationRequest, this);
}
}
public void setUpLocation() {
if (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
|| ContextCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
} else {
if (checkPlayServices()) {
if (statusSwitch.isChecked()) {
initAPIClient();
makeLocationRequest();
displayLocation();
}
} else {
Snackbar.make(getActivity().findViewById(android.R.id.content), "Google Play Services Not Supported on Your Device", Snackbar.LENGTH_LONG).show();
}
}
}
private void makeLocationRequest() {
locationRequest = LocationRequest.create();
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
locationRequest.setInterval(UPDATE_INTERVAL);
locationRequest.setFastestInterval(FASTEST_INTERVAL);
locationRequest.setSmallestDisplacement(DISPLACEMENT);
}
public boolean checkPlayServices() {
int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getActivity());
if (resultCode != ConnectionResult.SUCCESS) {
if (GooglePlayServicesUtil.isUserRecoverableError(resultCode)) {
GooglePlayServicesUtil.getErrorDialog(resultCode, getActivity(), AppConstants.PLAY_SERVICES_RESOLUTION_REQUEST).show();
} else {
Snackbar.make(getActivity().findViewById(android.R.id.content), "Play Services NOT Supported on Your Device", Snackbar.LENGTH_LONG).show();
getActivity().finish();
getActivity().moveTaskToBack(true);
}
return false;
}
return true;
}
private void initAPIClient() {
apiClient = new GoogleApiClient.Builder(getActivity())
.enableAutoManage(getActivity(), 0, this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
apiClient.connect();
}
public void stopLocationListener() {
if (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
|| ContextCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
} else {
LocationServices.FusedLocationApi.removeLocationUpdates(apiClient, this);
}
}
public void displayLocation() {
if (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
|| ContextCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, AppConstants.LOC_PERM_CODE);
} else {
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(apiClient);
if (mLastLocation != null) {
if (statusSwitch.isChecked()) {
latitude = mLastLocation.getLatitude();
longitude = mLastLocation.getLongitude();
Log.d(TAG, "Locn:\t" + "lat:\t" + latitude + "and long:\t" + longitude);
geoFire.setLocation("saj9oPN15VZODBbB87JXU26Rqa53", new GeoLocation(latitude, longitude), new GeoFire.CompletionListener() {
#Override
public void onComplete(String key, DatabaseError error) {
if (currentMarker != null) {
currentMarker.remove();
currentMarker.setIcon(BitmapDescriptorFactory.fromResource(R.drawable.car));
currentMarker = mGmap.addMarker(new MarkerOptions().position(new LatLng(latitude, longitude)));
LatLng latLng = new LatLng(latitude, longitude);
CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(latLng, 17f);
mGmap.animateCamera(cameraUpdate);
//draw rotate marker animation
//rotateMarker(currentMarker, -360, mGmap);
}
}
});
}
}
}
}
private void rotateMarker(final Marker currentMarker, final float i, GoogleMap mGmap) {
final Handler handler = new Handler();
final long start = SystemClock.uptimeMillis();
final float startRotation = currentMarker.getRotation();
final int duration = 1500;
final Interpolator interpolator = new LinearInterpolator();
handler.postDelayed(new Runnable() {
#Override
public void run() {
long elapsed = SystemClock.elapsedRealtime() - start;
float t = interpolator.getInterpolation(elapsed / duration);
float rot = t * i + (1 - t) * startRotation;
currentMarker.setRotation(-rot > 180 ? rot / 2 : rot);
if (t < 1.0) {
handler.postDelayed(this, 16);
}
}
}, duration);
}
#Override
public void onConnected(#Nullable Bundle bundle) {
startLocationListener();
displayLocation();
}
#Override
public void onConnectionSuspended(int i) {
apiClient.connect();
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
if (apiClient != null) {
apiClient = null;
initAPIClient();
}
}
#Override
public void onLocationChanged(Location location) {
mLastLocation = location;
displayLocation();
}
#Override
public void onMapReady(GoogleMap googleMap) {
mGmap = googleMap;
}
}
Can anyone help me understand why it's not working.

Related

Android app crash after sign in and logcat screen shows error?

I am making an app like uber and i have to put driver location with marker on app and
after sign in it shows loading and then crashes?
i have imported all libraries properly but my logcat screen
i have tried going to similar questions on stackOverflow but nothing seems working and this bug just shows again and again and i am not unable to start my app .
Welcome Activity
{
private GoogleMap mMap;
//Play Services
private static final int MY_PERMISSION_REQUEST_CODE=7000;
private static final int PLAY_SERVICE_RES_REQUEST= 7001;
private LocationRequest mLocationRequest;
private GoogleApiClient mGoogleApiClient;
private Location mLastLocation;
private static int UPDATE_INTERVAL = 5000;
private static int FATEST_INTERVAL = 3000;
private static int DISPLACEMENT = 10;
DatabaseReference drivers;
GeoFire geoFire;
Marker mCurrent;
MaterialAnimatedSwitch location_switch;
SupportMapFragment mapFragment;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_welcome);
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
//Init View
location_switch = (MaterialAnimatedSwitch)findViewById(R.id.location_switch);
location_switch.setOnCheckedChangeListener(new MaterialAnimatedSwitch.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(boolean isOnline) {
if (isOnline)
{
startLocationUpdates();
displayLocation();
Snackbar.make(mapFragment.getView(),"You are Online",Snackbar.LENGTH_SHORT)
.show();
}
else
{
stopLocationUpdates();
mCurrent.remove();
Snackbar.make(mapFragment.getView(),"You are Offline",Snackbar.LENGTH_SHORT)
.show();
}
}
});
//Geo Fire
drivers = FirebaseDatabase.getInstance().getReference("Drivers");
geoFire = new GeoFire(drivers);
setUpLocation();
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
switch (requestCode){
case MY_PERMISSION_REQUEST_CODE:
if (grantResults.length >0 && grantResults[0] == PackageManager.PERMISSION_GRANTED)
{
if (checkPlayServices())
{
buildGoogleApiClient();
createLocationRequest();
if(location_switch.isChecked())
displayLocation();
}
}
}
}
private void setUpLocation() {
if(ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED )
{
//Request runtime Permission
ActivityCompat.requestPermissions(this, new String[]{
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION
},MY_PERMISSION_REQUEST_CODE);
}
else
{
if (checkPlayServices())
{
buildGoogleApiClient();
createLocationRequest();
if(location_switch.isChecked())
displayLocation();
}
}
}
private void createLocationRequest() {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(UPDATE_INTERVAL);
mLocationRequest.setFastestInterval(FATEST_INTERVAL);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setSmallestDisplacement(DISPLACEMENT);
}
private void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
mGoogleApiClient.connect();
}
private boolean checkPlayServices() {
int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if(resultCode != ConnectionResult.SUCCESS)
{
if(GooglePlayServicesUtil.isUserRecoverableError(resultCode))
GooglePlayServicesUtil.getErrorDialog(resultCode,this,PLAY_SERVICE_RES_REQUEST).show();
else {
Toast.makeText(this, "This Device is not Supported", Toast.LENGTH_SHORT).show();
finish();
}
return false;
}
return true;
}
private void stopLocationUpdates() {
if(ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED )
{
return;
}
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient,this);
}
private void displayLocation() {
if(ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED )
{
return;
}
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (mLastLocation != null)
{
if (location_switch.isChecked())
{
final double latitude = mLastLocation.getLatitude();
final double longitude = mLastLocation.getLongitude();
//Update to Firebase
geoFire.setLocation(FirebaseAuth.getInstance().getCurrentUser().getUid(), new GeoLocation(latitude, longitude), new GeoFire.CompletionListener() {
#Override
public void onComplete(String key, DatabaseError error) {
//Add Marker
if (mCurrent != null)
mCurrent.remove(); //Remove already Marker
mCurrent = mMap.addMarker(new MarkerOptions()
.icon(BitmapDescriptorFactory.fromResource(R.drawable.lender))
.position(new LatLng(latitude,latitude))
.title("You"));
//Move the camera to this position
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(latitude,longitude),15.0f));
//Draw Animation Rotate Marker
rotateMarker(mCurrent,-360,mMap);
}
});
}
}
else
{
Log.d("ERROR","Cannot Get Your Location");
}
}
private void rotateMarker(final Marker mCurrent, final float i, GoogleMap mMap) {
final Handler handler = new Handler();
final long start = SystemClock.uptimeMillis();
final float startRotation = mCurrent.getRotation();
final long duration = 1500;
final Interpolator interpolator = new LinearInterpolator();
handler.post(new Runnable() {
#Override
public void run() {
long elapsed = SystemClock.uptimeMillis() - start ;
float t = interpolator.getInterpolation((float)elapsed/duration);
float rot = t*i+(1-t)*startRotation;
mCurrent.setRotation(-rot > 180?rot/2:rot);
if(t<1.0)
{
handler.postDelayed(this,16);
}
}
});
}
private void startLocationUpdates() {
if(ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED )
{
return;
}
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient,mLocationRequest,this);
}
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
}
#Override
public void onLocationChanged(Location location) {
mLastLocation = location;
displayLocation();
}
#Override
public void onConnected(#Nullable Bundle bundle) {
displayLocation();
startLocationUpdates();
}
#Override
public void onConnectionSuspended(int i) {
mGoogleApiClient.connect();
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
}
}

Drawing a polyline as I move

I want to make my first app to add a polyline in the map as i move (route tracking). I want to start draw the polyline when i press ButtonStart and stop when i press ButtonEnd. When i run it, it does not draw the polyline.
I run it in my phone and i disconnect it from the pc so i can move and see if it will draw the polyline.
public class MapsActivityCreateNewPath extends FragmentActivity implements
OnMapReadyCallback,
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,
LocationListener, View.OnClickListener {
private GoogleMap mMap;
private GoogleApiClient googleApiClient;
private LocationRequest locationRequest;
private Location lastLocation;
private Marker currentUserLocationMarker;
private static final int Request_User_Location_Code = 99;
private ArrayList<LatLng> listPoints;
Polyline line;
int count = 0;
Button ButtonStart;
Button ButtonEnd;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps_create_new_path);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
{
checkUserLocationPermission();
}
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
listPoints = new ArrayList<LatLng>();
ButtonStart = (Button) findViewById(R.id.ButtonStart);
ButtonEnd = (Button) findViewById(R.id.ButtonEnd);
if (count == 0)
{
ButtonEnd.setEnabled(false);
ButtonStart.setEnabled(true);
}
ButtonStart.setOnClickListener(new View.OnClickListener(){public void onClick (View v) {next_page(v);}});
ButtonEnd.setOnClickListener(new View.OnClickListener() {public void onClick (View v) {next_page(v);}});
}
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED)
{
buildGoogleApiClient();
mMap.setMyLocationEnabled(true);
}
}
public boolean checkUserLocationPermission()
{
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED)
{
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION))
{
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, Request_User_Location_Code);
}
else
{
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, Request_User_Location_Code);
}
return false;
}
else
{
return true;
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults)
{
switch (requestCode)
{
case Request_User_Location_Code:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED)
{
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED)
{
if (googleApiClient == null)
{
buildGoogleApiClient();
}
mMap.setMyLocationEnabled(true);
}
}
else
{
Toast.makeText(this, "Permission Denied...", Toast.LENGTH_SHORT).show();
}
return;
}
}
protected synchronized void buildGoogleApiClient()
{
googleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
googleApiClient.connect();
}
#Override
public void onLocationChanged(Location location) {
lastLocation = location;
if (currentUserLocationMarker != null)
{
currentUserLocationMarker.remove();
}
LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(latLng);
markerOptions.title("user Current Location");
markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_ORANGE));
currentUserLocationMarker = mMap.addMarker(markerOptions);
mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
mMap.animateCamera(CameraUpdateFactory.zoomBy(14));
if (googleApiClient != null)
{
LocationServices.FusedLocationApi.removeLocationUpdates(googleApiClient, this);
}
double latitude = location.getLatitude();
double longitude = location.getLongitude();
LatLng latLng1 = new LatLng(latitude, longitude);
listPoints.add(latLng1);
redrawLine();
}
#Override
public void onConnected(#Nullable Bundle bundle) {
locationRequest = new LocationRequest();
locationRequest.setInterval(1100);
locationRequest.setFastestInterval(1100);
locationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED)
{
LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, locationRequest, this);
}
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
}
public void next_page(View v){
switch(v.getId())
{
case R.id.ButtonStart:
count++;
ButtonStart.setEnabled(false);
ButtonEnd.setEnabled(true);
break;
case R.id.ButtonEnd:
count--;
ButtonStart.setEnabled(true);
ButtonEnd.setEnabled(false);
break;
}
if (count == 1) {
redrawLine();
}
}
#Override
public void onClick(View v) {
}
private void redrawLine()
{
if (count == 0)
{
return;
}
mMap.clear();
PolylineOptions options = new PolylineOptions().width(5).color(Color.BLUE).geodesic(true);
for (int i = 0; i < listPoints.size(); i++)
{
LatLng point = listPoints.get(i);
options.add(point);
}
line = mMap.addPolyline(options);
}
}

I'm making an app like uber and i used FusedLocationApi but it crashes

public class Welcome extends FragmentActivity implements OnMapReadyCallback,
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,
LocationListener
{
private GoogleMap mMap;
private static final int MY_PERMISSION_REQUEST_CODE = 7000;
private static final int PLAY_SERVICE_RES_REQUEST = 7001;
private LocationRequest mLocationRequest;
private GoogleApiClient googleApiClient;
private Location mLastLocation;
private static int UPDATE_INTERVAL = 5000;
private static int FATEST_INTERVAL = 3000;
private static int DISPLACMENT = 10;
DatabaseReference drivers;
GeoFire geoFire;
Marker mCurrent;
MaterialAnimatedSwitch animatedSwitch;
SupportMapFragment mapFragment;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
animatedSwitch = (MaterialAnimatedSwitch) findViewById(R.id.location_switch);
animatedSwitch.setOnCheckedChangeListener(new MaterialAnimatedSwitch.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(boolean isOnline) {
if (isOnline){
startLocationUpdates();
displayLocation();
Snackbar.make(mapFragment.getView(),"you are online!!",Snackbar.LENGTH_SHORT).show();
}
else {
stopLocationUpdates();
mCurrent.remove();
Snackbar.make(mapFragment.getView(),"you are offline!!",Snackbar.LENGTH_SHORT).show();
}
}
});
drivers = FirebaseDatabase.getInstance().getReference("Drivers");
geoFire = new GeoFire(drivers);
setUpLocation();
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
switch (requestCode)
{
case MY_PERMISSION_REQUEST_CODE:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
if (checkPlayServices()) {
buildGoogleApiClient();
createLocationRequest();
if (animatedSwitch.isChecked())
displayLocation();
}
}
}
}
private void setUpLocation() {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION ) != PackageManager.PERMISSION_GRANTED &&
ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION )!= PackageManager.PERMISSION_GRANTED)
{
ActivityCompat.requestPermissions(this , new String[]{
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION
},MY_PERMISSION_REQUEST_CODE);
}
else {
if (checkPlayServices()) {
buildGoogleApiClient();
createLocationRequest();
if (animatedSwitch.isChecked()) {
displayLocation();
}
}
}
}
private void createLocationRequest() {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(UPDATE_INTERVAL);
mLocationRequest.setFastestInterval(FATEST_INTERVAL);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setSmallestDisplacement(DISPLACMENT);
}
private void buildGoogleApiClient() {
googleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
googleApiClient.connect();
}
private boolean checkPlayServices() {
int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if (resultCode != ConnectionResult.SUCCESS) {
if (GooglePlayServicesUtil.isUserRecoverableError(resultCode))
GooglePlayServicesUtil.getErrorDialog(resultCode, this, PLAY_SERVICE_RES_REQUEST).show();
else {
Toast.makeText(this, "This device is not supported", Toast.LENGTH_SHORT).show();
finish();
}
return false;
}
return true;
}
private void stopLocationUpdates() {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION ) != PackageManager.PERMISSION_GRANTED &&
ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION )!= PackageManager.PERMISSION_GRANTED)
{
return;
}
LocationServices.FusedLocationApi.removeLocationUpdates(googleApiClient, (com.google.android.gms.location.LocationListener) this);
}
private void displayLocation() {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION ) != PackageManager.PERMISSION_GRANTED &&
ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION )!= PackageManager.PERMISSION_GRANTED)
{
return;
}
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(googleApiClient);
if(mLastLocation != null) {
if (animatedSwitch.isChecked()) {
final double latitude = mLastLocation.getLatitude();
final double longtitiude = mLastLocation.getLongitude();
geoFire.setLocation(FirebaseAuth.getInstance().getCurrentUser().getUid(), new GeoLocation(latitude, longtitiude), new GeoFire.CompletionListener() {
#Override
public void onComplete(String key, DatabaseError error) {
if(mCurrent != null) {
mCurrent.remove();
mCurrent = mMap.addMarker(new MarkerOptions()
.icon(BitmapDescriptorFactory.fromResource(R.drawable.car)).position(new LatLng(latitude,longtitiude)).title("you"));
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(latitude,longtitiude),15.0f));
rotateMArker(mCurrent,-360,mMap);
}
}
});
}
}
else {
Log.d("ERROR","Cannot find your Location");
}
}
private void rotateMArker(final Marker mCurrent, final float i, GoogleMap mMap) {
final Handler handler = new Handler();
final long start = SystemClock.uptimeMillis();
final float startRotating = mCurrent.getRotation();
final long duration = 1500;
final Interpolator interpolator = new LinearInterpolator();
handler.post(new Runnable() {
#Override
public void run() {
long elapsed = SystemClock.uptimeMillis() - start;
float t = interpolator.getInterpolation((float)elapsed/duration);
float rot = t*i+(1-t)*startRotating;
mCurrent.setRotation(-rot > 180?rot/2:rot);
if (t<1.0) {
handler.postDelayed(this,16);
}
}
});
}
private void startLocationUpdates() {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION ) != PackageManager.PERMISSION_GRANTED &&
ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION )!= PackageManager.PERMISSION_GRANTED)
{
return;
}
LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient,mLocationRequest, (com.google.android.gms.location.LocationListener) this);
}
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
}
#Override
public void onLocationChanged(Location location) {
mLastLocation = location;
displayLocation();
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
#Override
public void onConnected(#Nullable Bundle bundle) {
displayLocation();
startLocationUpdates();
}
#Override
public void onConnectionSuspended(int i) {
googleApiClient.connect();
}
It crashes every time because FusedLocationApi is deprecated.
I tried so many things but it doesn't work it crashes and crashes
how to replace the FusedLocationApi.

Location Permission Not Switching on With Device

I have implemented location using FusedLocationProviderClient. The problem in my app is that the permission dialog does not switch on the location in settings. I have to manually turn it on before I start getting updates.
I have checked and requested permission using ContextCompat and ActivityCompat classes but nothing happens until I manually press the button. Is this a bug with FusedLocationProviderClient or bad programming on my side? I have worked with location manager and Fused Location Provider APIs and never faced this before.
Here's my code:
public class HomeFragment extends BaseFragment implements OnMapReadyCallback {
private static final String TAG = HomeFragment.class.getSimpleName();
private Toolbar toolbar;
private TextView driverStatusTV;
public static MaterialAnimatedSwitch statusSwitch;
private FusedLocationProviderClient providerClient;
public static Location mLastLocation;
public static LocationRequest locationRequest;
public GoogleMap mGmap;
public static Marker currentMarker;
public static double latitude = 0f, longitude = 0f;
private static boolean isLocationGranted = false;
public static final int UPDATE_INTERVAL = 15000;
public static final int FASTEST_INTERVAL = 8000;
public static final int DISPLACEMENT = 10;
public static final int PLAY_SERVICES_REQ_CODE = 9009;
public static final int PLAY_SERVICES_RESOLUTION_REQ_CODE = 9090;
private SupportMapFragment mapFragment;
public HomeFragment() {
// Required empty public constructor
}
private void initViews(View view) {
toolbar = view.findViewById(R.id.toolbar);
driverStatusTV = view.findViewById(R.id.driverStatusTV);
statusSwitch = view.findViewById(R.id.statusSwitch);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_home, container, false);
initViews(view);
((AppCompatActivity) getActivity()).setSupportActionBar(toolbar);
checkPerms();
providerClient = LocationServices.getFusedLocationProviderClient(getActivity());
mapFragment = (SupportMapFragment) this.getChildFragmentManager().findFragmentById(R.id.mapFragment);
mapFragment.getMapAsync(this);
driverStatusTV.setText("OFFLINE");
statusSwitch.setOnCheckedChangeListener(new MaterialAnimatedSwitch.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(boolean b) {
if (b) {
Snackbar.make(getActivity().findViewById(android.R.id.content), "You are Now Online", Snackbar.LENGTH_LONG).show();
if (checkPerms()) {
startLocationListener();
driverStatusTV.setText("ONLINE");
}
} else {
Snackbar.make(getActivity().findViewById(android.R.id.content), "You are Now Offline", Snackbar.LENGTH_LONG).show();
mGmap.setIndoorEnabled(false);
if (ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
mGmap.setMyLocationEnabled(false);
stopLocationListener();
driverStatusTV.setText("OFFLINE");
if (currentMarker != null){
currentMarker.remove();
}
}
}
});
return view;
}
private void stopLocationListener() {
if (providerClient != null){
providerClient.removeLocationUpdates(locationCallback);
}
}
#Override
public void onPause() {
super.onPause();
stopLocationListener();
}
private void startLocationListener() {
locationRequest = LocationRequest.create();
locationRequest.setSmallestDisplacement(DISPLACEMENT);
locationRequest.setFastestInterval(FASTEST_INTERVAL);
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
locationRequest.setInterval(UPDATE_INTERVAL);
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
builder.addLocationRequest(locationRequest);
LocationSettingsRequest settingsRequest = builder.build();
SettingsClient client = LocationServices.getSettingsClient(getActivity());
client.checkLocationSettings(settingsRequest);
displayLocation();
}
private boolean checkPerms() {
if (ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
reqPerms();
isLocationGranted = false;
Log.d(TAG, "Permission Value:\t" + isLocationGranted);
} else {
isLocationGranted = true;
Log.d(TAG, "Permission Value:\t" + isLocationGranted);
}
return isLocationGranted;
}
private void reqPerms() {
ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, AppConstants.LOC_PERM_CODE);
}
private void displayLocation() {
if (ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
reqPerms();
} else {
if (statusSwitch.isChecked()) {
providerClient.requestLocationUpdates(locationRequest, locationCallback, Looper.myLooper());
mGmap.setIndoorEnabled(true);
mGmap.setMyLocationEnabled(true);
} else {
mGmap.setIndoorEnabled(false);
mGmap.setMyLocationEnabled(false);
}
}
}
private LocationCallback locationCallback = new LocationCallback() {
#Override
public void onLocationResult(LocationResult locationResult) {
Location location = locationResult.getLastLocation();
mLastLocation = location;
if (currentMarker != null) {
currentMarker.remove();
}
latitude = mLastLocation.getLatitude();
Log.d(TAG, "Lat:\t" + latitude);
longitude = mLastLocation.getLongitude();
Log.d(TAG, "Long:\t" + longitude);
MarkerOptions options = new MarkerOptions();
options.position(new LatLng(latitude, longitude));
options.title("Driver");
//options.icon(BitmapDescriptorFactory.fromResource(R.drawable.car)); // throws error
currentMarker = mGmap.addMarker(options);
rotateMarker(currentMarker, 360, mGmap);
mGmap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(latitude,longitude), 18.0f));
}
};
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case AppConstants.LOC_PERM_CODE:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
isLocationGranted = true;
if (checkPlayServices() && statusSwitch.isChecked()) {
startLocationListener();
} else {
Snackbar.make(getActivity().findViewById(android.R.id.content), "Google Play Services Not Supported on Your Device", Snackbar.LENGTH_LONG).show();
}
}
break;
}
}
public boolean checkPlayServices() {
int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getActivity());
if (resultCode != ConnectionResult.SUCCESS) {
if (GooglePlayServicesUtil.isUserRecoverableError(resultCode)) {
GooglePlayServicesUtil.getErrorDialog(resultCode, getActivity(), AppConstants.PLAY_SERVICES_RESOLUTION_REQUEST).show();
} else {
Snackbar.make(getActivity().findViewById(android.R.id.content), "Play Services NOT Supported on Your Device", Snackbar.LENGTH_LONG).show();
getActivity().finish();
getActivity().moveTaskToBack(true);
}
return false;
}
return true;
}
private void rotateMarker(final Marker currentMarker, final float i, GoogleMap mGmap) {
final Handler handler = new Handler();
final long start = SystemClock.uptimeMillis();
final float startRotation = currentMarker.getRotation();
final int duration = 1500;
final Interpolator interpolator = new LinearInterpolator();
handler.postDelayed(new Runnable() {
#Override
public void run() {
long elapsed = SystemClock.elapsedRealtime() - start;
float t = interpolator.getInterpolation(elapsed / duration);
float rot = t * i + (1 - t) * startRotation;
currentMarker.setRotation(-rot > 180 ? rot / 2 : rot);
if (t < 1.0) {
handler.postDelayed(this, 16);
}
}
}, duration);
}
#Override
public void onMapReady(GoogleMap googleMap) {
mGmap = googleMap;
startLocationListener();
}
}
Alos, the set icon on marker throws this error com.google.maps.api.android.lib6.common.apiexception.b: Failed to decode image. The provided image must be a Bitmap.
Can anyone help me solve these two problems? Thank you
your onRequestPermissionsResult will never be called, you are requesting permissions from your activity and your activity's onRequestPermissionsResult would be getting invoked. If you want permission callback in your fragment just remove Activity when you request permssions
private void reqPerms() {
requestPermissions(getActivity(), new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, AppConstants.LOC_PERM_CODE);
}
Your fragment has to be a supportFragment if you want to access this method

wait till the GPS is enabled before getting the lat and long value in FusedLocationAPI

I am trying to get current location using FusedLocationAPI in my application. It works just fine in both android API>23 and <23. The issue is in case of GPS is not enabled, the app prompts the user to enable the GPS and after that the location returns null. But while restarting the app, it works just fine. In case of GPS not being turned OFF, the app just works fine. Is there any way that the app can wait for the GPS to be enabled before getting the location? below I am posting my code. Please have a look.
Inside onCreate():
manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
statusOfGPS = manager.isProviderEnabled(LocationManager.GPS_PROVIDER);
if (!statusOfGPS) {
displayPromptForEnablingGPS(this);
}
Log.d("permipart", "before");
if(CheckingPermissionIsEnabledOrNot())
{
Toast.makeText(MainActivity.this, "All Permissions Granted Successfully", Toast.LENGTH_LONG).show();
}
else {
RequestMultiplePermission();
}
if(Build.VERSION.SDK_INT<= 23)
{
buildGoogleApiClient();
if (!mGoogleApiClient.isConnected()) {
mGoogleApiClient.connect();
}
}
Log.d("permipart", "out");
Other methods:
#Override
public void onLocationChanged(Location location) {
Log.d("onconnectedlocchange","called");
if (location != null) {
lat = location.getLatitude();
lon = location.getLongitude();
if (!String.valueOf(lat).equals("0.0"))
{
latitudeVal = location.getLatitude();
longitudeVal = location.getLongitude();
Log.e("Lat and Lng", String.valueOf(latitudeVal) + longitudeVal);
}
}
}
#Override
public void onConnected(#Nullable Bundle bundle) {
if(CheckingPermissionIsEnabledOrNot())
{
Toast.makeText(MainActivity.this, "All Permissions Granted Successfully", Toast.LENGTH_LONG).show();
}
// If, If permission is not enabled then else condition will execute.
else {
//Calling method to enable permission.
RequestMultiplePermission();
}
Log.d("onconnected","called");
mLocationRequest = LocationRequest.create();
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
// Update location every second
if (ActivityCompat.checkSelfPermission(this, ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
}
else
{
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
mGoogleApiClient);
if (mLastLocation != null) {
lat = mLastLocation.getLatitude();
lon = mLastLocation.getLongitude();
if (!String.valueOf(lat).equals("0.0")){
latitudeVal = mLastLocation.getLatitude();
longitudeVal = mLastLocation.getLongitude();
Log.e("Lat and Lng", String.valueOf(latitudeVal)+ longitudeVal);
}
}
}
}
#Override
public void onConnectionSuspended(int i) {
}
synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
}
public void displayPromptForEnablingGPS(final Activity activity) {
final android.support.v7.app.AlertDialog.Builder builder = new android.support.v7.app.AlertDialog.Builder(activity);
final String action = Settings.ACTION_LOCATION_SOURCE_SETTINGS;
final String message = "Do you want open GPS setting?";
builder.setMessage(message)
.setPositiveButton("OK",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface d, int id) {
activity.startActivity(new Intent(action));
d.dismiss();
}
})
.setNegativeButton("Cancel",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface d, int id) {
d.cancel();
}
});
builder.create().show();
}
String[] permissions = new String[]{ACCESS_FINE_LOCATION,
ACCESS_COARSE_LOCATION, READ_EXTERNAL_STORAGE, WRITE_EXTERNAL_STORAGE };
//Permission function starts from here
private void RequestMultiplePermission() {
// Creating String Array with Permissions.
Log.d("permipart", "RequestMultiplePermission");
ActivityCompat.requestPermissions(MainActivity.this, new String[]
{
READ_EXTERNAL_STORAGE,
WRITE_EXTERNAL_STORAGE,
ACCESS_FINE_LOCATION,
ACCESS_COARSE_LOCATION
}, RequestPermissionCode);
}
private boolean checkPermission() {
int result;
List<String> listPermissionsNeeded = new ArrayList<>();
for (String p:permissions) {
result = ContextCompat.checkSelfPermission(this,p);
if (result != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(p);
}
}
if (!listPermissionsNeeded.isEmpty()) {
ActivityCompat.requestPermissions(this, listPermissionsNeeded.toArray(new String[listPermissionsNeeded.size()]),10 );
Log.d("permissionissue","no");
return false;
}
Log.d("permissionissue","yes");
return true;
}
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
Log.d("permipart", "onRequestPermissionsResult");
switch (requestCode) {
case RequestPermissionCode:
if (grantResults.length > 0) {
boolean CameraPermission = grantResults[0] == PackageManager.PERMISSION_GRANTED;
boolean RecordAudioPermission = grantResults[1] == PackageManager.PERMISSION_GRANTED;
boolean SendSMSPermission = grantResults[2] == PackageManager.PERMISSION_GRANTED;
boolean GetAccountsPermission = grantResults[3] == PackageManager.PERMISSION_GRANTED;
if (CameraPermission && RecordAudioPermission && SendSMSPermission && GetAccountsPermission) {
Log.d("permipart", "done");
buildGoogleApiClient();
Toast.makeText(MainActivity.this, "Permission Granted", Toast.LENGTH_LONG).show();
if (!mGoogleApiClient.isConnected()) {
mGoogleApiClient.connect();
}
}
else {
Toast.makeText(MainActivity.this,"Permission Denied",Toast.LENGTH_LONG).show();
}
}
break;
}
}
/**
* Checking permission is enabled or not using function starts from here.
*
*/
public boolean CheckingPermissionIsEnabledOrNot() {
int FirstPermissionResult = ContextCompat.checkSelfPermission(getApplicationContext(), READ_EXTERNAL_STORAGE);
int SecondPermissionResult = ContextCompat.checkSelfPermission(getApplicationContext(), WRITE_EXTERNAL_STORAGE);
int ThirdPermissionResult = ContextCompat.checkSelfPermission(getApplicationContext(), ACCESS_FINE_LOCATION);
int ForthPermissionResult = ContextCompat.checkSelfPermission(getApplicationContext(), ACCESS_COARSE_LOCATION);
return FirstPermissionResult == PackageManager.PERMISSION_GRANTED &&
SecondPermissionResult == PackageManager.PERMISSION_GRANTED &&
ThirdPermissionResult == PackageManager.PERMISSION_GRANTED &&
ForthPermissionResult == PackageManager.PERMISSION_GRANTED ;
}
You need to recieve the broadcast of the GPS status something like this:
public class GpsLocationReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().matches("android.location.PROVIDERS_CHANGED")) {
// here you can get the location or start a service to get it.
// example
// Intent getLocationService = new Intent(context,YourService.class);
// context.startService(getLocationService);
}
}
}
update
according to comment below
use this in your code
manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
if(manager.isProviderEnabled( LocationManager.GPS_PROVIDER)){
// it is enabled
}else{
// it is not
}
Use my code, it will ask the user to turn on GPS if it is turned off. It will never return you anything until GPS turned on.
Note: you have to get location permission before using it for marshmallow and above mobiles.
Try this:
#SuppressWarnings("MissingPermission")
public class LocationFinder implements LocationListener, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
public static final String TAG = "LocationFinder";
private static final String BROADCAST_GPS_REQ = "LocationFinder.GPS_REQ";
private static final String KEY_GPS_REQ = "key.gps.req";
private static final int GPS_REQUEST = 2301;
private Activity activity;
private FinderType finderType;
private GoogleApiClient googleApiClient;
private LocationRequest locationRequest;
private long updateInterval;
private long fastestInterval;
private GpsRequestListener gpsRequestListener;
private LocationUpdateListener locationUpdateListener;
public LocationFinder(Activity activity, FinderType finderType) {
this.activity = activity;
this.finderType = finderType;
}
private void connectGoogleApiClient() {
googleApiClient = new GoogleApiClient.Builder(activity)
.addApi(LocationServices.API).addConnectionCallbacks(this)
.addOnConnectionFailedListener(this).build();
googleApiClient.connect();
}
private void createLocationRequest() {
locationRequest = LocationRequest.create();
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
locationRequest.setInterval(updateInterval);
locationRequest.setFastestInterval(fastestInterval);
}
private BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
int intExtra = intent.getIntExtra(KEY_GPS_REQ, 0);
switch (intExtra) {
case Activity.RESULT_OK:
try {
LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, locationRequest, LocationFinder.this);
} catch (Exception e) {
e.printStackTrace();
}
gpsRequestListener.gpsTurnedOn();
break;
case Activity.RESULT_CANCELED:
gpsRequestListener.gpsNotTurnedOn();
}
}
};
public void gpsRequestCallback(GpsRequestListener gpsRequestListener) {
this.gpsRequestListener = gpsRequestListener;
LocalBroadcastManager.getInstance(activity).registerReceiver(receiver, new IntentFilter(BROADCAST_GPS_REQ));
}
public void config(long updateInterval, long fastestInterval) {
this.updateInterval = updateInterval;
this.fastestInterval = fastestInterval;
}
public void find(LocationUpdateListener listener) {
this.locationUpdateListener = listener;
createLocationRequest();
connectGoogleApiClient();
}
private void find() {
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
.addLocationRequest(locationRequest);
builder.setAlwaysShow(true);
PendingResult<LocationSettingsResult> result = LocationServices.SettingsApi.checkLocationSettings(googleApiClient, builder.build());
result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
#Override
public void onResult(#NonNull LocationSettingsResult locationSettingsResult) {
Status status = locationSettingsResult.getStatus();
switch (status.getStatusCode()) {
case LocationSettingsStatusCodes.SUCCESS:
LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, locationRequest, LocationFinder.this);
break;
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
try {
status.startResolutionForResult(activity, GPS_REQUEST);
} catch (IntentSender.SendIntentException e) {
e.printStackTrace();
}
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
Log.d(TAG, "No GPS Hardware");
break;
}
}
});
}
public void stopFinder() {
if (googleApiClient.isConnected()) {
LocationServices.FusedLocationApi.removeLocationUpdates(googleApiClient, this);
googleApiClient.disconnect();
}
try {
activity.unregisterReceiver(receiver);
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void onConnected(#Nullable Bundle bundle) {
Log.d(TAG, "GoogleApiClient: Connected");
find();
}
#Override
public void onConnectionSuspended(int i) {
Log.d(TAG, "GoogleApiClient: onConnectionSuspended");
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
Log.d(TAG, "GoogleApiClient: onConnectionFailed");
}
#Override
public void onLocationChanged(Location location) {
if (finderType != FinderType.TRACK)
stopFinder();
locationUpdateListener.onLocationUpdate(new LatLng(location.getLatitude(), location.getLongitude()));
}
public void setGpsRequestListener(GpsRequestListener gpsRequestListener) {
this.gpsRequestListener = gpsRequestListener;
}
public static void onRequestResult(Activity activity, int requestCode, int resultCode) {
if (requestCode == GPS_REQUEST) {
Intent intent = new Intent(BROADCAST_GPS_REQ);
intent.putExtra(KEY_GPS_REQ, resultCode);
LocalBroadcastManager.getInstance(activity).sendBroadcast(intent);
}
}
public enum FinderType {
// It will update the current GPS location once.
GPS,
//It will update the user location continuously.
TRACK
}
public interface LocationUpdateListener {
void onLocationUpdate(LatLng latLng);
}
public interface GpsRequestListener {
void gpsTurnedOn();
void gpsNotTurnedOn();
}
}
To get location update initialize the class like this:
public class MyActivity extends AppCompatActivity implements
LocationFinder.GpsRequestListener,
LocationFinder.LocationUpdateListener {
private LocationFinder locationUpdater;
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
locationUpdater = new LocationFinder(this, LocationFinder.FinderType.TRACK);
driverLocationUpdater.gpsRequestCallback(this);
driverLocationUpdater.config(5000, 5000);
driverLocationUpdater.find(this);
}
#Override
protected void onDestroy(){
super.onDestroy()
driverLocationUpdater.stopFinder();
}
#Override
public void onLocationUpdate(LatLng latLng) {
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
LocationFinder.onRequestResult(this, requestCode, resultCode);
}
}

Categories

Resources