Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NoSuchMethodError com.google.android.gms.internal.g.f

I have a difficult problem to solve. I've published my app on Play and everything is okay, but the problem is that there are 2 devices that crashes the app with the following error:

java.lang.NoSuchMethodError: java.io.IOException.<init>
at com.google.android.gms.internal.g.f(Unknown Source)
at com.google.android.gms.internal.g.b(Unknown Source)
at com.google.android.gms.internal.e.a(Unknown Source)
at com.google.android.gms.internal.e.a(Unknown Source)
at com.google.android.gms.internal.bq.ac(Unknown Source)
at com.google.android.gms.internal.cg$1.run(Unknown Source)
at com.google.android.gms.internal.ch$1.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561)
at java.lang.Thread.run(Thread.java:1096)

I just know this error because Play shows me, but it's impossible to see where it is. Besides, I have another information. Here is the thing: It happens when the user chooses to see the map in a drawer menu and the error is in the first time he chooses.

Here is the code of this fragment:

package br.ufc.ondefica.fragments;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import br.ufc.ondefica.MainActivity;
import br.ufc.ondefica.R;
import br.ufc.ondefica.model.Placemark;
import br.ufc.ondefica.utils.DataHelper;
import br.ufc.ondefica.utils.ParserKML;

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.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;

public class UFCMapFragment extends FragmentWithSearch {
    private GoogleMap map;
    private int positionToShow = 3;
    private boolean isDefaultView = true;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View root = inflater.inflate(R.layout.map_layout, container, false);
        ((MainActivity) getActivity()).setTitle(getResources().getStringArray(R.array.sliding_menu)[0]);
        return root;
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        map = ((SupportMapFragment) getActivity().getSupportFragmentManager()
                .findFragmentById(R.id.map)).getMap();
        map.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
        map.setMyLocationEnabled(true);
        Bundle bundle = getArguments();
        if (bundle != null && bundle.containsKey("positionToShow")) {
            isDefaultView = false;
            positionToShow = bundle.getInt("positionToShow");
        }
        loadMap();
        // Move the camera instantly to the default place to show with a zoom of
        // 15.
        map.moveCamera(CameraUpdateFactory.newLatLngZoom(DataHelper.data.places
                .get(positionToShow).getCoordinates(), 13));
        // Zoom in, animating the camera.
        map.animateCamera(CameraUpdateFactory.zoomTo(16), 4000, null);
    }

    private void loadMap() {
        for (int i = 0; i < DataHelper.data.places.size(); i++) {
            Placemark place = DataHelper.data.places.get(i);
            Marker marker = map.addMarker(new MarkerOptions()
                    .icon(BitmapDescriptorFactory.fromResource(ParserKML
                            .loadMapOfIcons(place.getIconID())))
                    .title(place.getName()).snippet(place.getDescription())
                    .position(place.getCoordinates()));
            if (i == positionToShow && !isDefaultView)
                marker.showInfoWindow();
        }
    }

    public void onDestroyView() {
        super.onDestroyView();
        Fragment fragment = (getFragmentManager().findFragmentById(R.id.map));
        FragmentTransaction ft = getActivity().getSupportFragmentManager()
                .beginTransaction();
        ft.remove(fragment);
        ft.commit();
    }
}

The devices that crashes are: Samsung Galaxy ACE (GT-S5830B) and Samsung Galaxy 5 (GT-I5500B). Thanks in advance,

like image 513
Renan Bandeira Avatar asked Nov 19 '13 20:11

Renan Bandeira


1 Answers

The first line on the stracktrace give you a clue:

java.lang.NoSuchMethodError: java.io.IOException.<init>

Basically it's saying that some constructor for IOException is missing. Looking at the javadocs, there are two constructors that were added in API level 9:

public IOException (Throwable cause)
public IOException (String message, Throwable cause)

That should answer your question. API level 9 is Android 2.3. Hence, the stack trace is from a device running Android 2.2 or below, which is missing the two constructors above.

There are at least two solutions to solve the problem:

  • Change the minSdkVersion in your app's manifest to 9.
  • Don't use the latest Google Play Services library, but use the Froyo version in stead.

The latter you can find in the SDK Manager. It was added with the last update because support for Froyo (Android 2.2) was dropped. Quote from the linked blog post:

With over 97% of devices now running Android 2.3 (Gingerbread) or newer platform versions, we’re dropping support for Froyo from this release of the Google Play services SDK in order to make it possible to offer more powerful APIs in the future. That means you will not be able to utilize these new APIs on devices running Android 2.2 (Froyo).

like image 180
MH. Avatar answered Oct 12 '22 02:10

MH.