-1

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)
Shubham Sharma
  • 2,763
  • 5
  • 31
  • 46

2 Answers2

2

Before calling 'addresses.get(0)' you should check that the size is greater than 0.

dev.bmax
  • 8,998
  • 3
  • 30
  • 41
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

Community
  • 1
  • 1
insomniac
  • 11,146
  • 6
  • 44
  • 55