Android IndexOutOfBoundsException: Index: 1, Size:

2019-09-19 03:30发布

问题:

I'm new to using SQLite on Android and I have some error here.

I have this app:

http://imgur.com/gallery/The7Q

With the code below I can click on the save button and on the first item on the list, in this case London, then go to the location of the place.

But When I add a second place and try to to the above I get a:

java.lang.IndexOutOfBoundsException: Index: 1, Size: 1

On this line:

 //Centralize the selected item
        Orientation selectedLocation = geocodingResult.getResults().get(getIntent().getIntExtra(SELECTED_POSITION, 1)).getGeometry().getLocation();

How to I solve this?

Map Activity:

public class MapActivity extends AppCompatActivity {

private GoogleMap map;
private GeocodeResult geocodingResult;

List<Address> listAddresses;

String address = "";

public LatLng latlng;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_maps);

    map = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.activity_map_googlemap)).getMap();

    addMarkers();
}

 // Show the markers on the map
public void addMarkers() {
    Geocoder geocoder = new Geocoder(getApplicationContext(), Locale.getDefault());
    geocodingResult = getIntent().getParcelableExtra(MainActivity.RESULT);

    if (geocodingResult != null) {
        //  For each Geocoding object, get the results markers
        for (Geocoding geocoding : geocodingResult.getResults()) {
            map.addMarker(new MarkerOptions()
                    .position(new LatLng(geocoding.getGeometry().getLocation().getLat(), geocoding.getGeometry().getLocation().getLng()))
                    .icon(BitmapDescriptorFactory.defaultMarker())
                    .title(geocoding.getFormattedAddress()) //location name that will be shown when click the marker
                    .snippet(String.valueOf(geocoding.getGeometry().getLocation().getLat())
                            + ", "
                            + String.valueOf(geocoding.getGeometry().getLocation().getLng())) //coordinates that will be shown when click the marker
            );
            try {
                latlng = new LatLng(geocoding.getGeometry().getLocation().getLat(), geocoding.getGeometry().getLocation().getLng());
                listAddresses = geocoder.getFromLocation(geocoding.getGeometry().getLocation().getLat(), geocoding.getGeometry().getLocation().getLng(), 1); // Here 1 represent max location result to returned, by documents it recommended 1 to 5
            } catch (IOException e) {
                e.printStackTrace();
            }
            Log.d("LIST", String.valueOf(listAddresses));
        }


        //Centralize the selected item
        Orientation selectedLocation = geocodingResult.getResults().get(getIntent().getIntExtra(SELECTED_POSITION, 1)).getGeometry().getLocation();
        map.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(selectedLocation.getLat(), selectedLocation.getLng()), 4));
    }
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    super.onCreateOptionsMenu(menu);

    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.menu_main, menu);

    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {

    Geocoder geocoder = new Geocoder(getApplicationContext(), Locale.getDefault());

    if (item.getItemId() == R.id.save) {

        try {

            List<Address> listAddresses = geocoder.getFromLocation(latlng.latitude, latlng.longitude, 1);

            if (listAddresses != null && listAddresses.size() > 0) {

                if (listAddresses.get(0).getLocality() != null) {

                    if (listAddresses.get(0).getPostalCode() != null) {

                        address += listAddresses.get(0).getLocality() + " ";

                    }

                    address += listAddresses.get(0).getPostalCode();

                }
            }
            Log.d("LIST", String.valueOf(listAddresses));
        } catch (IOException e) {
            e.printStackTrace();
        }

        if (address == "") {

            SimpleDateFormat sdf = new SimpleDateFormat("HH:mm yyyy-MM-dd");

            address = sdf.format(new Date());
        }

        DBController crud = new DBController(getBaseContext());
        String result;
        result = crud.insertData(address, latlng.latitude, latlng.longitude);
        Log.d("ADDRESS", address);
        Log.d("LAT", String.valueOf(latlng.latitude));
        Log.d("LNG", String.valueOf(latlng.longitude));
        Toast.makeText(getApplicationContext(), result, Toast.LENGTH_LONG).show();
    }

    return super.onOptionsItemSelected(item);
}// END MENU

Main:

public class MainActivity extends AppCompatActivity {

public final static String RESULT = "listGeocoding";
public final static String SELECTED_POSITION = "selectedPosition";

public static ListView listView;
EditText edtSearch;
Button btnSearch;

GeocodeResult geocodingResult;
Dialog dialogProgress;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    edtSearch = (EditText) findViewById(R.id.edtSearch);
    btnSearch = (Button) findViewById(R.id.btnSearch);

    listView = (ListView) findViewById(R.id.listView);

    setListeners();

}// END ON CREATE

//  Set Listeners to the activity
private void setListeners() {

    //region Button click jump to SearchAddress method
    btnSearch.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            searchAddress();
        }
    });
    //endregion

    //region List View Click jump to MapActivity
    listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            Intent intent = new Intent(MainActivity.this, MapActivity.class);
            intent.putExtra(RESULT, geocodingResult);
            intent.putExtra(SELECTED_POSITION, position);
            startActivity(intent);
        }
    });
    //endregion
}// END METHOD

//region Deal with orientation changes
@Override
protected void onSaveInstanceState(Bundle outState) {
    outState.putParcelable(RESULT, geocodingResult);
    super.onSaveInstanceState(outState);
}

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
    geocodingResult = savedInstanceState.getParcelable(RESULT);

    if (geocodingResult != null && geocodingResult.getResults().size() > 0) {
        loadResult();
    }
}
//endregion

//region Search method
private void searchAddress() {
    //region Deal with the keyboard and user input
    CommonUtils.hideKeyboard(MainActivity.this, edtSearch);

    //  Ask the user for the address if not provided
    if (edtSearch.getText().toString().equals("")) {
        Toast.makeText(MainActivity.this, "Please enter an address", Toast.LENGTH_SHORT).show();
        return; //  pause and await for response
    }
    //endregion

    listView.setVisibility(View.GONE);
    showProgress();

        //region Search the address
        GoogleMaps service = ServiceGenerator.createService(GoogleMaps.class, "http://maps.googleapis.com");    //  API URL
        service.getGeocoding(edtSearch.getText().toString(), true, new Callback<GeocodeResult>() {
            @Override
            public void success(GeocodeResult googleGeocodingResult, Response response) {
                hideProgress();
                geocodingResult = googleGeocodingResult;

                if (geocodingResult.getResults().size() > 0) {
                    loadResult();
                } else {
                    Toast.makeText(MainActivity.this, "Didn't find a place.", Toast.LENGTH_SHORT).show();
                }
            }

            @Override
            public void failure(RetrofitError error) {
                hideProgress();
                Toast.makeText(MainActivity.this, error.getMessage(), Toast.LENGTH_SHORT).show();
            }
        });
        //endregion
}

private void loadResult() {
    listView.setVisibility(View.VISIBLE);
    listView.setAdapter(new Adapter(MainActivity.this, geocodingResult.getResults()));
}
//endregion

//region Progress Dialog
private void showProgress() {
    if (dialogProgress == null) {
        dialogProgress = new Dialog(this);
        dialogProgress.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dialogProgress.setContentView(R.layout.custom_progress);
        dialogProgress.setCancelable(false);
    }
    dialogProgress.getWindow().getDecorView().getRootView();
    dialogProgress.show();
}

private void hideProgress() {
    if (dialogProgress != null) {
        dialogProgress.dismiss();
        dialogProgress = null;
    }
}
//endregion

//region Menu
@Override
public boolean onCreateOptionsMenu(Menu menu) {

    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.menu_main, menu);
    return super.onCreateOptionsMenu(menu);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {

    if (item.getItemId() == R.id.save){
        Intent intent = new Intent(getApplicationContext(), Query.class);
        intent.putExtra(RESULT, geocodingResult);
        startActivity(intent);
    }
    return super.onOptionsItemSelected(item);
}

Query:

    import static com.arthurabreu.memorableplaces.MainActivity.RESULT;
import static com.arthurabreu.memorableplaces.MainActivity.SELECTED_POSITION;


/**
 * Created by blitz on 4/8/2017.
 */

public class Query extends AppCompatActivity {

    private ListView list;
    private GeocodeResult geocodingResult;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.list_view_query);

        DBController crud = new DBController(getBaseContext());
        Cursor cursor = crud.loadData();

        String[] titles = new String[] {SQLite.ID, SQLite.KEY_TITLE};
        int[] idViews = new int[] {R.id.idNumber, R.id.idTitle};


        SimpleCursorAdapter adapter = new SimpleCursorAdapter(getBaseContext(),
                R.layout.adapter_query_layout,cursor,titles,idViews, 0);
        list = (ListView)findViewById(R.id.listView);
        list.setAdapter(adapter);


        list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, final int position, long id) {

                final Cursor c = ((SimpleCursorAdapter)list.getAdapter()).getCursor();
                c.moveToPosition(position);
                String place = c.getString(1); //Get the name of the place saved in the cursor
                Log.d("TEST", String.valueOf(c.getString(1)));

                //region Search the address
                GoogleMaps service = ServiceGenerator.createService(GoogleMaps.class, "http://maps.googleapis.com");    //  API URL
                service.getGeocoding(place, true, new Callback<GeocodeResult>() {
                    @Override
                    public void success(GeocodeResult googleGeocodingResult, Response response) {

                        geocodingResult = googleGeocodingResult;

                        if (geocodingResult.getResults().size() > 0) {
                            Intent intent = new Intent(getApplicationContext(), MapActivity.class);
                            intent.putExtra(RESULT, geocodingResult);
                            intent.putExtra(SELECTED_POSITION, position);
                            Log.d("POSITION", String.valueOf(position));
                            startActivity(intent);
                        } else {
                            Toast.makeText(getApplicationContext(), "Didn't find a place.", Toast.LENGTH_SHORT).show();
                        }
                    }

                    @Override
                    public void failure(RetrofitError error) {

                        Toast.makeText(getApplicationContext(), error.getMessage(), Toast.LENGTH_SHORT).show();
                    }
                });
                //endregion

            }// END ON CLICK
        });

    }// END ONCREATE
}// ENDMAIN

回答1:

Your error occurs when the coding can't reach the specific index. You may check on this thread.

IndexOutOfBound exception means you've got a problem because you're trying to access an index which doesn't exist or is empty (not null). For example if you've got an array with only two elements, so it only has index 0 and 1, and you try to access index 2 you'll get an IndexOutOfBoundException because index 2 doesn't exist. If you make an array of 10 elements and only fill 5, indexes 4-9 will be empty, accessing those might cause an IndexOutOfBoundException.

Here's a possible workaround on how to fix this:

If you're using an IDE it might help you to debug the problem by removing the throws statements. Throws statements "pass the buck" when it comes to exceptions, you're not actually handling exceptions by using throws. Try-catch statements handle exceptions much better because they narrow down the area where the problem is (because they 'test' the code within the try brackets.

Throws have their place, but for debugging try-catch can be much more helpful.

Additional references:

  • Google Maps android IndexOutOfBoundsException
  • Java ArrayList IndexOutOfBoundsException Index: 1, Size: 1