Shows Location.getLatitude() a null object despite use of Request location updates? - android

I am a newbie to android programming and i have been attempting to use geofence to activate alaram services in my app. It worked fine until one day it showed Null pointer reference to double.getlatitude(). I have searched websites with no result. i have used requestLocationUpdates to get updates from the user location.
Here is my code-
package saksham.geofencing;
import android.Manifest;
import android.app.Service;
import android.content.Context;
import android.content.pm.PackageManager;
import android.database.sqlite.SQLiteDatabase;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.view.View;
import android.widget.Toast;
import com.google.android.gms.location.Geofence;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import java.util.ArrayList;
public class MapsActivity extends FragmentActivity implements LocationListener{
private GoogleMap googleMap; // Might be null if Google Play services APK is not available.
public SQLiteDatabase db;
ArrayList<Geofence> mGeofences;
public double latitude=77.80;
public double longitude=55.76;
Double valueindex=0.0;
private int request=0;
/**
* Geofence Coordinates
*/
ArrayList<LatLng> mGeofenceCoordinates;
/**
* Geofence Store
*/
private GeofenceStore mGeofenceStore;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mGeofences = new ArrayList<Geofence>();
mGeofenceCoordinates = new ArrayList<LatLng>();
db = openOrCreateDatabase("CoordsDB", Context.MODE_PRIVATE, null);
// db.execSQL("CREATE TABLE IF NOT EXISTS Coordinates(number DOUBLE,latitude DOUBLE,longitude DOUBLE);");
// db.execSQL("INSERT INTO Coordinates VALUES('Fixed', 28.61,77.20)");
setContentView(R.layout.activity_maps);
SupportMapFragment supportMapFragment =
(SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.googleMap);
/**
* SupportMapFragment belongs to the v4 support library, contrary to the default MagFragment that is a native component in Android.
SupportMapFragment will support more Android versions, but it is also an additional library you have to add in your project,
so I think it really depends on the Android versions you are targeting:
• On recent versions, the default components should be enough
• On older versions you will need to install the v4 support library and maybe others
*
*/
googleMap = supportMapFragment.getMap();
Log.i("My activity", "maps=" + googleMap);
googleMap.setMyLocationEnabled(true);
/**
* setMyLocationEnabled(true/false) shows the true location when the GPS is switched on from the device. It is an inbuilt feature of the googlemaps .
*/
LocationManager locationManager = (LocationManager) getSystemService(Service.LOCATION_SERVICE);
// getting GPS status
boolean isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
Log.i("My activity", "gps is" +isGPSEnabled);
// getting network status
boolean isNetworkEnabled = locationManager
.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
Log.i("My activity", "network is" +isNetworkEnabled);
Criteria crta = new Criteria();
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.GINGERBREAD) {
crta.setAccuracy(Criteria.ACCURACY_FINE);
}else{
crta.setAccuracy(Criteria.ACCURACY_MEDIUM);
}
/**
* we have used .setAccuracy as fine for higher SDks than gingerbread .Gingerbread is used as a reference because in apks lower
* than gingerbread there is very poor geofencing, with gingerbread google made it a lot easier for locationservices to be used for devleopers.
* it had improved set of tools for Location Services, which included geofencing and substantially improved location discovery.
*/
crta.setPowerRequirement(Criteria.POWER_LOW);
String provider = locationManager.getBestProvider(crta, true);
/**
* It request Location updates after every 5 sec or if the user traveled 10m
*/
Log.i("My activity", "manager is " + locationManager);
Log.i("My activity", "provider is " + provider);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
MapsActivity.this.requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 100);
// 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 Activity#requestPermissions for more details.
return;
}
}
Location location = locationManager.getLastKnownLocation(provider);
Log.i("Location is", location + "");
if (location != null) {
onLocationChanged(location);
}
else
{
locationManager.requestLocationUpdates(provider,
( 1000),0, this);
Log.i("REached here","here");
onLocationChanged(location);
}
/**
* the Permission is requested after every 5 sec or at a distance of 2 metres by the user.
*/
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case 100: {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "Thanks for the permission", Toast.LENGTH_LONG).show();
// permission was granted, yay! do the
// calendar task you need to do.
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
Toast.makeText(this, "You did not allow to access your current location", Toast.LENGTH_LONG).show();
}
}
// other 'switch' lines to check for other
// permissions this app might request
}
}
#Override
public void onLocationChanged(Location location) {
CameraPosition INIT =
new CameraPosition.Builder()
.target(new LatLng(location.getLatitude(),location.getLongitude()))
.zoom( 17.5F )
.bearing( 300F) // orientation
.tilt( 50F) // viewing angle
.build();
// use GooggleMap mMap to move camera into position
googleMap.animateCamera(CameraUpdateFactory.newCameraPosition(INIT));
}
#Override
protected void onStart() {
super.onStart();
}
#Override
protected void onStop() {
// mGeofenceStore.disconnect();
super.onStop();
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
public void Add(View view) {
if (request <= 3) {
mGeofenceCoordinates.add(new LatLng(latitude, longitude));
Log.i("The id is", "" + valueindex);
mGeofences.add(new Geofence.Builder()
// The coordinates of the center of the geofence and the radius in meters.
.setRequestId("" + valueindex)
.setCircularRegion(latitude, longitude, 30)
.setExpirationDuration(Geofence.NEVER_EXPIRE)
// Required when we use the transition type of GEOFENCE_TRANSITION_DWELL
.setLoiteringDelay(50000)
.setTransitionTypes(
Geofence.GEOFENCE_TRANSITION_ENTER
| Geofence.GEOFENCE_TRANSITION_DWELL
| Geofence.GEOFENCE_TRANSITION_EXIT).build());
mGeofenceStore = new GeofenceStore(this, mGeofences);
valueindex++;
request++;
// Cursor c = db.rawQuery("SELECT * FROM Coordinates WHERE Id='"+valueindex+"'", null);
googleMap.addMarker(new MarkerOptions().snippet("Radius:30m").draggable(false).title(valueindex + "").position(new LatLng(latitude,longitude)));
}
else{
Toast.makeText(this,"Maximum limit exceeded",Toast.LENGTH_LONG).show();
}
}
}
and here is my Logcat-
Process: saksham.geofencing, PID: 12102
java.lang.RuntimeException: Unable to start activity ComponentInfo{saksham.geofencing/saksham.geofencing.MapsActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'double android.location.Location.getLatitude()' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2426)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2490)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1354)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5443)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'double android.location.Location.getLatitude()' on a null object reference
at saksham.geofencing.MapsActivity.onCreate(MapsActivity.java:122)
at android.app.Activity.performCreate(Activity.java:6245)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1130)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2379)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2490)
            at android.app.ActivityThread.-wrap11(ActivityThread.java)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1354)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:148)
            at android.app.ActivityThread.main(ActivityThread.java:5443)
            at java.lang.reflect.Method.invoke(Native Method)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
01-24 02:11:14.268 12102-12102/saksham.geofencing I/Process﹕ Sending signal. PID: 12102 SIG: 9
please help!!!

Use the fused location api ... this is from an intent service so you will need to just pick out the pieces you need... also are you using the emulator? if so the last known location always used to give me trouble/null values.. are you telneting in and using geofix?
package geoimage.ret.geoimage;
import android.app.IntentService;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
/**
* An {#link IntentService} subclass for handling asynchronous task requests in
* a service on a separate handler thread.
* <p/>
* TODO: Customize class - update intent actions, extra parameters and static
* helper methods.
*/
public class GetLocationService extends IntentService implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {
// TODO: Rename actions, choose action names that describe tasks that this
// IntentService can perform, e.g. ACTION_FETCH_NEW_ITEMS
private static final String ACTION_LOCATION = "location";
LocationRequest mLocationRequest;
GoogleApiClient mGoogleApiClient;
public GetLocationService() {
super("GetLocationService");
}
/**
* Starts this service to perform action Baz with the given parameters. If
* the service is already performing a task this action will be queued.
*
* #see IntentService
*/
// TODO: Customize helper method
public static void startGetLocation(Context context) {
Intent intent = new Intent(context, GetLocationService.class);
intent.setAction(ACTION_LOCATION);
context.startService(intent);
}
#Override
protected void onHandleIntent(Intent intent) {
if (intent != null) {
final String action = intent.getAction();
if (ACTION_LOCATION.equals(action)) {
handleLocation();
}
}
}
/**
* Handle action Baz in the provided background thread with the provided
* parameters.
*/
private void handleLocation() {
// TODO: Handle action Baz
if (mGoogleApiClient == null) {
buildGoogleApiClient();
}
mGoogleApiClient.connect();
}
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
#Override
public void onConnected(Bundle bundle) {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(1);
mLocationRequest.setFastestInterval(1);
mLocationRequest.setNumUpdates(1);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
sendBroadcast(connectionResult.getErrorMessage());
}
#Override
public void onLocationChanged(Location location) {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
App.setLat(location.getLatitude());
App.setLon(location.getLongitude());
mGoogleApiClient.disconnect();
sendBroadcast("LocationObtained");
}
private void sendBroadcast(String errStatus) {
Intent intent = new Intent("location");
intent.putExtra("status", errStatus);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
stopSelf();
}
}

You are manually calling onLocationChanged() with a null value in the else branch here:
if (location != null) {
onLocationChanged(location);
}
else
{
locationManager.requestLocationUpdates(provider,
( 1000),0, this);
Log.i("REached here","here");
// location is null here
onLocationChanged(location);
}
When you request location updates, the onLocationChanged callback will be called by the LocationManager.

The LocationListener which you're implementing is from the google api, that import is this:
import com.google.android.gms.location.LocationListener;
and not this:
import android.location.LocationListener;
It's also important that the LocationClient is connected before you do this. Also don't call it in the onCreate or onStart methods, but in onResume. For more detail go through: https://developer.android.com/training/location/index.html

Related

Can't get user location using Google Play Services API Android

I have been trying to work with Google Play Services in my android app to get the user location but the MapsActivity seems not to update the location. I have tried out three tutorials but none of them seems to solve the issue of getting the user's location.
MapsActivity.java
package com.whitewebteam.deliverus;
import android.content.IntentSender;
import android.content.pm.PackageManager;
import android.location.Location;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.FragmentActivity;
import android.os.Bundle;
import android.util.Log;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback,
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,
LocationListener {
private GoogleMap map;
private GoogleApiClient googleApiClient;
private LocationRequest locationRequest;
public static final String TAG = MapsActivity.class.getSimpleName();
private final static int CONNECTION_FAILURE_RESOLUTION_REQUEST = 9000;
#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.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
if (googleApiClient == null) {
googleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
locationRequest = LocationRequest.create()
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
.setInterval(10000)
.setFastestInterval(1000);
}
#Override
protected void onResume() {
super.onResume();
googleApiClient.connect();
}
#Override
protected void onPause() {
super.onPause();
if (googleApiClient.isConnected()) {
LocationServices.FusedLocationApi.removeLocationUpdates(googleApiClient, this);
googleApiClient.disconnect();
}
}
/**
* Manipulates the map once available.
* This callback is triggered when the map is ready to be used.
* This is where we can add markers or lines, add listeners or move the camera. In this case,
* we just add a marker near Sydney, Australia.
* If Google Play services is not installed on the device, the user will be prompted to install
* it inside the SupportMapFragment. This method will only be triggered once the user has
* installed Google Play services and returned to the app.
*/
#Override
public void onMapReady(GoogleMap googleMap) {
map = googleMap;
LatLng latLng = new LatLng(0, 0);
map.addMarker(new MarkerOptions().position(latLng).title("Marker"));
map.moveCamera(CameraUpdateFactory.newLatLng(latLng));
}
#Override
public void onConnected(#Nullable Bundle bundle) {
Log.i(TAG, "Location services connected.");
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.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;
}
Location lastLocation = LocationServices.FusedLocationApi.getLastLocation(googleApiClient);
if (lastLocation == null) {
LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, locationRequest, this);
}
else {
handleNewLocation(lastLocation);
}
}
private void handleNewLocation(Location location) {
Log.d(TAG, location.toString());
double currentLatitude = location.getLatitude();
double currentLongitude = location.getLongitude();
LatLng latLng = new LatLng(currentLatitude, currentLongitude);
MarkerOptions options = new MarkerOptions()
.position(latLng)
.title("I am here!");
map.addMarker(options);
map.moveCamera(CameraUpdateFactory.newLatLng(latLng));
}
#Override
public void onConnectionSuspended(int i) {
Log.i(TAG, "Location services suspended. Please reconnect.");
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
if (connectionResult.hasResolution()) {
try {
// Start an Activity that tries to resolve the error
connectionResult.startResolutionForResult(this, CONNECTION_FAILURE_RESOLUTION_REQUEST);
} catch (IntentSender.SendIntentException e) {
e.printStackTrace();
}
} else {
Log.i(TAG, "Location services connection failed with code " + connectionResult.getErrorCode());
}
}
#Override
public void onLocationChanged(Location location) {
handleNewLocation(location);
}
}
I have also added location access to my AndroidManifest.xml
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
and added the following dependencies in build.gradle:
compile 'com.google.android.gms:play-services-location:10.2.0'
compile 'com.google.android.gms:play-services-maps:10.2.0'
I had changed the dependencies from:
compile 'com.google.android.gms:play-services:10.2.0'
but it didn't solve the issue. The MapsActivity sticks to the default LatLag(0,0). Any help will be appreciated.

Getting GPS updates using fused location in background service For ex(15 mins)?

I'm new for android development need to get gps location in background service without user interaction like for every 15 mins need to fetch the coordinates and send the results to server how can i achieve this. Then i tried fused location api syncadapter combination.It works, i'm getting coordinates but i need to use that location class in dedicated android-service how can i achieve this need to make that service run for ever 15 mins fetch the coordinates and send that result to server let me post my Google api client class.Please check below code i have tried.
import android.content.Context;
import android.location.Location;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.util.Log;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.PendingResult;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.location.FusedLocationProviderApi;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import java.text.DateFormat;
import java.util.Date;
/**
* Created by 4264 on 14-10-2016.
*/
public class Locationlistener implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener,LocationListener {
LocationRequest mLocationRequest;
GoogleApiClient mGoogleApiClient;
Location mCurrentLocation;
String mLastUpdateTime;
private Context context;
private static final long INTERVAL = 1000 * 10;
private static final long FASTEST_INTERVAL = 1000 * 5;
public Locationlistener(Context c)
{
context=c;
//show error dialog if GoolglePlayServices not available
createLocationRequest();
mGoogleApiClient = new GoogleApiClient.Builder(context)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
mGoogleApiClient.connect();
}
protected void createLocationRequest() {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(INTERVAL);
mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
public String lat(){
String lat=null;
if(mCurrentLocation==null){
Log.d("is null","null");
}
else {
lat=String.valueOf(mCurrentLocation.getLatitude());
}
return lat;
}
protected void startLocationUpdates() {
PendingResult<Status> pendingResult = LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
Log.d("started", "Location update started ..............: ");
}
public void updateUI() {
Log.d("updated", "UI update initiated .............");
if (null != mCurrentLocation) {
String lat = String.valueOf(mCurrentLocation.getLatitude());
String lng = String.valueOf(mCurrentLocation.getLongitude());
Log.e("latw",lat);
Log.e("Long",lng);
} else {
Log.d("", "location is null ...............");
}
}
#Override
public void onConnected(Bundle bundle) {
Log.d("connected", "onConnected - isConnected ...............: " + mGoogleApiClient.isConnected());
startLocationUpdates();
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
Log.d("failed", "Connection failed: " + connectionResult.toString());
}
#Override
public void onLocationChanged(Location location) {
Log.d("locationchanged", "Firing onLocationChanged..............................................");
mCurrentLocation = location;
mLastUpdateTime = DateFormat.getTimeInstance().format(new Date());
updateUI();
}
}
It works in syncadapter but i need to make this in service how can i achieve this and another doubt if user turn off the gps how can i get location is it possible with network location updates thanks in advance!!
I would suggest you to use AlarmManager to wake up device and receive location as soon as possible (interval 0) then continue to sleep at each 15 minutes. So this approach better than non-stop service.
If user turns off the gps, you will be still getting (network provider) location updates but not accurate due to location settings aren't adequate. Also to solve this, you can use SettingsApi
When making a request to location services, the device's system settings may be in a state that prevents an app from obtaining the location data that it needs. For example, GPS or Wi-Fi scanning may be switched off.

my app is crashing every time i turn on the location when the app is running

My app is crashing every time I turn on the location when the app is running, I have also posted the log file below, it shows IndexOutOfBoundsException: Invalid index 0, size is 0, I searched this error for almost 2 days but unable to solve it please give any solution thankyou
import android.*;
import android.Manifest;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationManager;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.FragmentActivity;
import android.os.Bundle;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gms.appdatasearch.GetRecentContextCall;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.maps.model.PolylineOptions;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
public class MainActivit extends FragmentActivity implements OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener, GoogleMap.OnMarkerClickListener {
int REQUEST_ACCESS_FINE_LOCATION;
private GoogleMap mMap;
LocationRequest mLocationRequest;
Location currentLocation;
GoogleApiClient client;
double user_latitude;
double user_longitude;
TextView details;
boolean gps_enabled;
String address;
Context context;
int REQUEST_LOCATION;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 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);
client=new GoogleApiClient.Builder(this).addConnectionCallbacks(this).addOnConnectionFailedListener(this).addApi(LocationServices.API).build();
client.connect();
mLocationRequest=new LocationRequest();
details= (TextView) findViewById(R.id.txdetails);
}
/**
* Manipulates the map once available.
* This callback is triggered when the map is ready to be used.
* This is where we can add markers or lines, add listeners or move the camera. In this case,
* we just add a marker near Sydney, Australia.
* If Google Play services is not installed on the device, the user will be prompted to install
* it inside the SupportMapFragment. This method will only be triggered once the user has
* installed Google Play services and returned to the app.
*/
#TargetApi(Build.VERSION_CODES.M)
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED && checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
mMap.setMyLocationEnabled(true);
} else {
if (shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_FINE_LOCATION)) {
Toast.makeText(MainActivit.this, "Location permission is needed", Toast.LENGTH_SHORT).show();
}
requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_LOCATION);
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if (requestCode == REQUEST_LOCATION) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
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;
}
mMap.setMyLocationEnabled(true);
} else {
Toast.makeText(MainActivit.this, "Permission not granted", Toast.LENGTH_SHORT).show();
}
}
else {
super.onRequestPermissionsResult(requestCode,permissions,grantResults);
}
}
#Override
protected void onStart() {
Log.d("FUNCTION","onStart");
super.onStart();
client.connect();
}
#Override
protected void onStop() {
Log.d("FUNCTION","onStop");
client.disconnect();
super.onStop();
}
#Override
public void onConnected(Bundle bundle) {
Log.d("FUNCTION","onConnected");
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
mLocationRequest.setInterval(1000);
currentLocation= LocationServices.FusedLocationApi.getLastLocation(client);
if(currentLocation==null) {
Toast.makeText(this, "Could not fetch current location", Toast.LENGTH_LONG).show();
LocationServices.FusedLocationApi.requestLocationUpdates(client, mLocationRequest,this);
}
//If the retrieved location is not null place a marker at that position
else{
user_latitude = currentLocation.getLatitude();
user_longitude = currentLocation.getLongitude();
if (currentLocation != null)
Log.d("CURR LOCATION VAL", String.valueOf(currentLocation));
LatLng user_coordinates = new LatLng(currentLocation.getLatitude(), currentLocation.getLongitude());
LatLng cry_coordinates=new LatLng(13.071160, 80.240431);
LatLng eklavya_coordinated=new LatLng(13.043065, 80.273880);
mMap.addMarker(new MarkerOptions().position(user_coordinates).title("Marker at current location"));
mMap.moveCamera(CameraUpdateFactory.newLatLng(user_coordinates));
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(user_coordinates,10));
mMap.addMarker(new MarkerOptions().position(cry_coordinates).title("cry"));
mMap.addMarker(new MarkerOptions().position(eklavya_coordinated).title("Smile Foundation"));
mMap.setOnMarkerClickListener(this);
}
LocationServices.FusedLocationApi.requestLocationUpdates(client, mLocationRequest, this);
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onLocationChanged(Location location) {
currentLocation = location;
if (currentLocation == null) {
Toast.makeText(this, "could not fetch user location", Toast.LENGTH_SHORT).show();
} else {
LocationManager manager = (LocationManager) getSystemService(LOCATION_SERVICE);
gps_enabled = manager.isProviderEnabled(LocationManager.GPS_PROVIDER);
Geocoder geocoder = new Geocoder(this, Locale.getDefault());
if (gps_enabled) {
try {
//Implementing reverse geocoding to get the user address in readable format
List<Address> addresses = geocoder.getFromLocation(user_latitude, user_longitude, 1);
Address fetchedAddress = addresses.get(0);
StringBuilder strAddress = new StringBuilder();
for (int i = 0; i < fetchedAddress.getMaxAddressLineIndex(); i++) {
strAddress.append(fetchedAddress.getAddressLine(i));
strAddress.append(" ");
address = strAddress.toString();
details.setText(address);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
}
#Override
public boolean onMarkerClick(Marker marker) {
if(marker.getTitle().equals("cry")) { // if marker source is clicked
AlertDialog.Builder cry = new AlertDialog.Builder(this);
cry.setMessage("Child Rights and You commonly abbreviated as CRY is a non-profit organisation like other NGOs in India and aims to restore children's rights. The organisation was established in 1979");
cry.setPositiveButton("Donate",new DialogInterface.OnClickListener()
{
#Override
public void onClick(DialogInterface dialogInterface, int i) {
Intent intent=new Intent(MainActivit.this,Cry_Info.class);
startActivity(intent);
}
});
cry.setTitle("CRY");
AlertDialog alertDialog = cry.create();
alertDialog.show();
}
else if (marker.getTitle().equals("Smile Foundation"))
{
AlertDialog.Builder smile = new AlertDialog.Builder(this);
smile.setMessage("Smile Foundation is a national level development organisation directly benefitting over 400,000 children and their families every year, through 158 welfare projects on education, healthcare, livelihood and women empowerment, in more than 700 remote villages and slums across 25 states of India");
smile.setPositiveButton("Donate", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
Intent intent=new Intent(MainActivit.this,Eklavya_Info.class);
startActivity(intent);
}
});
smile.setTitle("SMILE FOUNDATION");
AlertDialog alertDialog = smile.create();
alertDialog.show();
}
return false;
}
}
ANDROID MONITOR ERROR
07-17 13:18:33.980 3815-3815/com.example.mactavish.code24_maps D/AndroidRuntime: Shutting down VM
07-17 13:18:33.990 3815-3815/com.example.mactavish.code24_maps E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.mactavish.code24_maps, PID: 3815
java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0
at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
at java.util.ArrayList.get(ArrayList.java:308)
at com.example.mactavish.code24_maps.MainActivit.onLocationChanged(MainActivit.java:225)
at com.google.android.gms.location.internal.zzk$zzb.handleMessage(Unknown Source)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5443)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
Before calling 'addresses.get(0)' you should check that the size is greater than 0.
The error says that it is unable to get the 0th item from the address array you get from the geocoder at MainActivit.onLocationChanged(MainActivit.java:225)
addresses.get(0);
The geocoder api in android is pretty unreliable you should use a fallback method like requesting to the Google geocode api
As shown here

how to stop receiving location update in google map android

i am making location tracking application.
For that i put two buttons stop and start, on start button click receiving location update is enable,
on stop button click stop receiving location update.
but stop receiving location update is not working.
package com.jaygandhi.tracking;
import android.Manifest;
import android.content.IntentSender;
import android.content.pm.PackageManager;
import android.location.Location;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.FragmentActivity;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
public class MapsActivity extends FragmentActivity implements
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,
LocationListener {
private Button bStop, bStart;
private boolean mRequestLocationUpdates = false;
private final static int PLAY_SERVICES_RESOLUTION_REQUEST = 1000;
public static final String TAG = MapsActivity.class.getSimpleName();
/*
* Define a request code to send to Google Play services
* This code is returned in Activity.onActivityResult
*/
private final static int CONNECTION_FAILURE_RESOLUTION_REQUEST = 9000;
private GoogleMap mMap; // Might be null if Google Play services APK is not available.
private GoogleApiClient mGoogleApiClient;
private LocationRequest mLocationRequest;
Marker mCurrLocationMarker;
private static int UPDATE_INTERVAL = 5 * 1000;
private static int FATEST_INTERVAL = 1 * 1000;
private static int DISPLACEMENT = 10;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
setUpMapIfNeeded();
bStart = (Button) findViewById(R.id.btnstart);
bStop = (Button) findViewById(R.id.btnstop);
if (checkPlayServices()) {
buildGoogleApiClient();
createLocationRequest();
}
/*mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
// Create the LocationRequest object
mLocationRequest = LocationRequest.create()
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
.setInterval(5 * 1000) // 10 seconds, in milliseconds
.setFastestInterval(1 * 1000); // 1 second, in milliseconds
*/
bStart.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//togglePeriodLocationUpdates();
startLocationUpdates();
}
});
bStop.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//togglePeriodLocationUpdates();
//stopLocationUpdates();
stopLocationUpdates();
}
});
}
/*public void st()
{
mRequestLocationUpdates = true;
startLocationUpdates();
}
public void sp()
{
mRequestLocationUpdates = false;
stopLocationUpdates();
}
*/
/*private void togglePeriodLocationUpdates()
{
if(!mRequestLocationUpdates)
{
mRequestLocationUpdates = true;
startLocationUpdates();
}
else
{
mRequestLocationUpdates = false;
stopLocationUpdates();
}
}*/
protected void startLocationUpdates() {
mRequestLocationUpdates = true;
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;
}
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
Log.d(TAG, String.valueOf(mRequestLocationUpdates));
//Log.d(TAG, String.valueOf(mGoogleApiClient));
}
protected void stopLocationUpdates()
{
mRequestLocationUpdates = false;
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
Log.d(TAG, String.valueOf(mRequestLocationUpdates));
}
#Override
protected void onStart()
{
super.onStart();
if(mGoogleApiClient != null)
{
mGoogleApiClient.connect();
//setUpMapIfNeeded();
}
}
#Override
protected void onResume()
{
super.onResume();
checkPlayServices();
//mGoogleApiClient.connect();
if(mGoogleApiClient.isConnected() )
{
if(mRequestLocationUpdates)
{
startLocationUpdates();
setUpMapIfNeeded();
}
}
}
#Override
protected void onStop()
{
super.onStop();
if(mGoogleApiClient.isConnected())
{
mGoogleApiClient.disconnect();
}
}
#Override
protected void onPause() {
super.onPause();
if (mGoogleApiClient.isConnected())
{
stopLocationUpdates();
}
}
/**
* Sets up the map if it is possible to do so (i.e., the Google Play services APK is correctly
* installed) and the map has not already been instantiated.. This will ensure that we only ever
* call {#link #setUpMap()} once when {#link #mMap} is not null.
* <p/>
* If it isn't installed {#link SupportMapFragment} (and
* {#link com.google.android.gms.maps.MapView MapView}) will show a prompt for the user to
* install/update the Google Play services APK on their device.
* <p/>
* A user can return to this FragmentActivity after following the prompt and correctly
* installing/updating/enabling the Google Play services. Since the FragmentActivity may not
* have been completely destroyed during this process (it is likely that it would only be
* stopped or paused), {#link #onCreate(Bundle)} may not be called again so we should call this
* method in {#link #onResume()} to guarantee that it will be called.
*/
private void setUpMapIfNeeded()
{
// Do a null check to confirm that we have not already instantiated the map.
if (mMap == null)
{
// Try to obtain the map from the SupportMapFragment.
mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map))
.getMap();
// Check if we were successful in obtaining the map.
if (mMap != null)
{
setUpMap();
}
}
}
/**
* This is where we can add markers or lines, add listeners or move the camera. In this case, we
* just add a marker near Africa.
* <p/>
* This should only be called once and when we are sure that {#link #mMap} is not null.
*/
private void setUpMap()
{
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;
}
mMap.setMyLocationEnabled(true);
mMap.addMarker(new MarkerOptions().position(new LatLng(0, 0)).title("Marker"));
}
private void handleNewLocation(Location location)
{
Log.d(TAG, location.toString());
double currentLatitude = location.getLatitude();
double currentLongitude = location.getLongitude();
LatLng latLng = new LatLng(currentLatitude, currentLongitude);
Toast.makeText(this, "Location Changed " + currentLatitude +" , "
+ currentLongitude, Toast.LENGTH_LONG).show();
if (mCurrLocationMarker != null)
{
mCurrLocationMarker.remove();
}
//mMap.addMarker(new MarkerOptions().position(new LatLng(currentLatitude, currentLongitude)).title("Current Location"));
MarkerOptions options = new MarkerOptions()
.position(latLng)
.title("I am here!");
mCurrLocationMarker= mMap.addMarker(options);
mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
mMap.animateCamera(CameraUpdateFactory.zoomTo(13));
}
#Override
public void onConnected(Bundle bundle)
{
Location location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (location == null)
{
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}
else
{
handleNewLocation(location);
}
}
#Override
public void onConnectionSuspended(int i)
{
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult)
{
/*
* Google Play services can resolve some errors it detects.
* If the error has a resolution, try sending an Intent to
* start a Google Play services activity that can resolve
* error.
*/
if (connectionResult.hasResolution()) {
try {
// Start an Activity that tries to resolve the error
connectionResult.startResolutionForResult(this, CONNECTION_FAILURE_RESOLUTION_REQUEST);
/*
* Thrown if Google Play services canceled the original
* PendingIntent
*/
} catch (IntentSender.SendIntentException e) {
// Log the error
e.printStackTrace();
}
}
else
{
/*
* If no resolution is available, display a dialog to the
* user with the error.
*/
Log.i(TAG, "Location services connection failed with code " + connectionResult.getErrorCode());
}
}
#Override
public void onLocationChanged(Location location)
{
handleNewLocation(location);
}
private boolean checkPlayServices()
{
int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if(resultCode != ConnectionResult.SUCCESS)
{
if(GooglePlayServicesUtil.isUserRecoverableError(resultCode))
{
GooglePlayServicesUtil.getErrorDialog(resultCode, this, PLAY_SERVICES_RESOLUTION_REQUEST).show();
}
else
{
Toast.makeText(getApplicationContext(), "This device is not supported", Toast.LENGTH_LONG)
.show();
finish();
}
return false;
}
return true;
}
protected synchronized void buildGoogleApiClient()
{
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API).build();
}
protected void createLocationRequest()
{
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(UPDATE_INTERVAL);
mLocationRequest.setFastestInterval(FATEST_INTERVAL);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setSmallestDisplacement(DISPLACEMENT);
}
}
Listening to location changes is better using a LocationManager and implementing LocationListener, you dont need GoogleClient to listen to the location updates.
To listen to locations update correctly you must do the following
//Declare a location manager
private LocationManager locationManager;
//Request location update either by GPS or NETWORK and for accurate results use //GPS
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 3, this);
//and the new locations will go to the onLocationChanged(Location location) //method that you already overrided
now to stop listening to the location updates just use this
locationManager.removeUpdates(this);

GoogleApiClient is not connected despite onconnect() being called?

I want to add a geofence on the current location of the user when the user clicks on the ad geofence button.however,after using fused api client it states that its not connected yet.here is my code-
import android.Manifest;
import android.app.Service;
import android.content.Context;
import android.content.pm.PackageManager;
import android.database.sqlite.SQLiteDatabase;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationManager;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.view.View;
import android.widget.Toast;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.Geofence;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import java.util.ArrayList;
public class MapsActivity extends FragmentActivity implements com.google.android.gms.location.LocationListener, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
private GoogleMap googleMap; // Might be null if Google Play services APK is not available.
public SQLiteDatabase db;
ArrayList<Geofence> mGeofences;
public double latitude = 77.80;
public double longitude = 55.76;
Double valueindex = 0.0;
private int request = 0;
private LocationRequest mLocationRequest;
private GoogleApiClient mGoogleApiClient;
/**
* Geofence Coordinates
*/
ArrayList<LatLng> mGeofenceCoordinates;
/**
* Geofence Store
*/
private GeofenceStore mGeofenceStore;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mGeofences = new ArrayList<Geofence>();
mGeofenceCoordinates = new ArrayList<LatLng>();
db = openOrCreateDatabase("CoordsDB", Context.MODE_PRIVATE, null);
// db.execSQL("CREATE TABLE IF NOT EXISTS Coordinates(number DOUBLE,latitude DOUBLE,longitude DOUBLE);");
// db.execSQL("INSERT INTO Coordinates VALUES('Fixed', 28.61,77.20)");
setContentView(R.layout.activity_maps);
SupportMapFragment supportMapFragment =
(SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.googleMap);
/**
* SupportMapFragment belongs to the v4 support library, contrary to the default MagFragment that is a native component in Android.
SupportMapFragment will support more Android versions, but it is also an additional library you have to add in your project,
so I think it really depends on the Android versions you are targeting:
• On recent versions, the default components should be enough
• On older versions you will need to install the v4 support library and maybe others
*
*/
googleMap = supportMapFragment.getMap();
Log.i("My activity", "maps=" + googleMap);
googleMap.setMyLocationEnabled(true);
/**
* setMyLocationEnabled(true/false) shows the true location when the GPS is switched on from the device. It is an inbuilt feature of the googlemaps .
*/
LocationManager locationManager = (LocationManager) getSystemService(Service.LOCATION_SERVICE);
// getting GPS status
boolean isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
Log.i("My activity", "gps is" + isGPSEnabled);
// getting network status
boolean isNetworkEnabled = locationManager
.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
Log.i("My activity", "network is" + isNetworkEnabled);
Criteria crta = new Criteria();
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.GINGERBREAD) {
crta.setAccuracy(Criteria.ACCURACY_FINE);
} else {
crta.setAccuracy(Criteria.ACCURACY_MEDIUM);
}
/**
* we have used .setAccuracy as fine for higher SDks than gingerbread .Gingerbread is used as a reference because in apks lower
* than gingerbread there is very poor geofencing, with gingerbread google made it a lot easier for locationservices to be used for devleopers.
* it had improved set of tools for Location Services, which included geofencing and substantially improved location discovery.
*/
crta.setPowerRequirement(Criteria.POWER_LOW);
String provider = locationManager.getBestProvider(crta, true);
/**
* It request Location updates after every 5 sec or if the user traveled 10m
*/
Log.i("My activity", "manager is " + locationManager);
Log.i("My activity", "provider is " + provider);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
MapsActivity.this.requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 100);
// 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 Activity#requestPermissions for more details.
return;
}
}
if (mGoogleApiClient == null) {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks((GoogleApiClient.ConnectionCallbacks) this)
.addOnConnectionFailedListener((GoogleApiClient.OnConnectionFailedListener) this)
.addApi(LocationServices.API)
.build();
mGoogleApiClient.connect();
Log.i("Api is",""+mGoogleApiClient);
}
mLocationRequest = new LocationRequest();
// We want a location update every 10 seconds.
mLocationRequest.setInterval(10000);
// We want the location to be as accurate as possible.
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
// Location location = locationManager.getLastKnownLocation(provider);
Location location = LocationServices.FusedLocationApi.getLastLocation(
mGoogleApiClient);
startLocationUpdates();
Log.i("Location is", location + "");
if (location != null) {
onLocationChanged(location);
}
/**
* the Permission is requested after every sec or at a distance of 0 metres by the user.
*/
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case 100: {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "Thanks for the permission", Toast.LENGTH_LONG).show();
// permission was granted, yay! do the
// calendar task you need to do.
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
Toast.makeText(this, "You did not allow to access your current location", Toast.LENGTH_LONG).show();
}
}
// other 'switch' lines to check for other
// permissions this app might request
}
}
#Override
public void onLocationChanged(Location location) {
CameraPosition INIT =
new CameraPosition.Builder()
.target(new LatLng(location.getLatitude(), location.getLongitude()))
.zoom(17.5F)
.bearing(300F) // orientation
.tilt(50F) // viewing angle
.build();
// use GooggleMap mMap to move camera into position
googleMap.animateCamera(CameraUpdateFactory.newCameraPosition(INIT));
}
#Override
protected void onStart() {
super.onStart();
mGoogleApiClient.connect();
}
#Override
protected void onStop() {
super.onStop();
mGoogleApiClient.disconnect();
}
public void Add(View view) {
if (request <= 3) {
mGeofenceCoordinates.add(new LatLng(latitude, longitude));
Log.i("The id is", "" + valueindex);
mGeofences.add(new Geofence.Builder()
// The coordinates of the center of the geofence and the radius in meters.
.setRequestId("" + valueindex)
.setCircularRegion(latitude, longitude, 30)
.setExpirationDuration(Geofence.NEVER_EXPIRE)
// Required when we use the transition type of GEOFENCE_TRANSITION_DWELL
.setLoiteringDelay(50000)
.setTransitionTypes(
Geofence.GEOFENCE_TRANSITION_ENTER
| Geofence.GEOFENCE_TRANSITION_DWELL
| Geofence.GEOFENCE_TRANSITION_EXIT).build());
mGeofenceStore = new GeofenceStore(this, mGeofences);
valueindex++;
request++;
// Cursor c = db.rawQuery("SELECT * FROM Coordinates WHERE Id='"+valueindex+"'", null);
googleMap.addMarker(new MarkerOptions().snippet("Radius:30m").draggable(false).title(valueindex + "").position(new LatLng(latitude, longitude)));
} else {
Toast.makeText(this, "Maximum limit exceeded", Toast.LENGTH_LONG).show();
}
}
#Override
public void onConnected(Bundle bundle) {
Location mlastlocation;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
MapsActivity.this.requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 100);
// public void requestPermissions(#NonNull String[] permissions, int requestCode)
// 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 Activity#requestPermissions for more details.
return;
}
}
mlastlocation = LocationServices.FusedLocationApi.getLastLocation(
mGoogleApiClient);
startLocationUpdates();
if (mlastlocation != null) {
Log.i("the last location:", "" + mlastlocation);
Toast.makeText(this, "Get last location first asshole!", Toast.LENGTH_LONG).show();
}
}
protected void startLocationUpdates() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
MapsActivity.this.requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 100);
// public void requestPermissions(#NonNull String[] permissions, int requestCode)
// 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 Activity#requestPermissions for more details.
return;
}
LocationRequest mLocationRequest = new LocationRequest();
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
}
}
#Override
public void onConnectionSuspended(int i) {
Log.i("connection","suspended");
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.i("Connection","Failed");
}
}
Here is my error-
java.lang.RuntimeException: Unable to start activity ComponentInfo{saksham.geofencing/saksham.geofencing.MapsActivity}: java.lang.IllegalStateException: GoogleApiClient is not connected yet.
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2426)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2490)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1354)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5443)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
Caused by: java.lang.IllegalStateException: GoogleApiClient is not connected yet.
at com.google.android.gms.common.api.internal.zzh.zzb(Unknown Source)
at com.google.android.gms.common.api.internal.zzl.zzb(Unknown Source)
at com.google.android.gms.common.api.internal.zzj.zzb(Unknown Source)
at com.google.android.gms.location.internal.zzd.requestLocationUpdates(Unknown Source)
at saksham.geofencing.MapsActivity.startLocationUpdates(MapsActivity.java:276)
at saksham.geofencing.MapsActivity.onCreate(MapsActivity.java:139)
at android.app.Activity.performCreate(Activity.java:6245)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1130)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2379)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2490)
            at android.app.ActivityThread.-wrap11(ActivityThread.java)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1354)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:148)
            at android.app.ActivityThread.main(ActivityThread.java:5443)
            at java.lang.reflect.Method.invoke(Native Method)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
and my manifest file-
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="saksham.geofencing" >
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
<!--
The ACCESS_COARSE/FINE_LOCATION permissions are not required to use
Google Maps Android API v2, but are recommended.
-->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="#string/google_maps_key" />
<activity
android:name=".MapsActivity"
android:label="#string/title_activity_maps" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<receiver android:name="com.aol.android.geofence.GeofenceReceiver"
android:exported="false">
<intent-filter >
<action android:name="com.aol.android.geofence.ACTION_RECEIVE_GEOFENCE"/>
</intent-filter>
</receiver>
</manifest>
Please help,i am newbie to android and i have been stuck at it for many days now even after searching countless blogs
In your onCreate method, you correctly configure the Google API Client and call onConnect:
if (mGoogleApiClient == null) {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks((GoogleApiClient.ConnectionCallbacks) this)
.addOnConnectionFailedListener((GoogleApiClient.OnConnectionFailedListener) this)
.addApi(LocationServices.API)
.build();
mGoogleApiClient.connect();
Log.i("Api is",""+mGoogleApiClient);
}
However, several lines below this (still within the onCreate lifecycle method), you have the following code:
Location location = LocationServices.FusedLocationApi.getLastLocation(
mGoogleApiClient);
startLocationUpdates();
Log.i("Location is", location + "");
if (location != null) {
onLocationChanged(location);
}
My guess is that the first line of this section is causing the error - you are trying to retrieve a location but the Google API Client is still not connected at this point. Since you already have analogous code inside your onConnected callback, you should be able to just remove the second block of code I quoted above from your onCreate method to fix the issue.

Categories

Resources