intellion
intellion

Reputation: 1437

Google Maps API v2 - Android Runtime shutting down when adding a marker

A have a rather simple view that contains a MapView. Everything works fine until I try to add a marker from a hash map with locations. There is a really bizzare debug message that the VM is shut down and the screen just turns black. No exceptions. I'm testing on Google Nexus 7 2013, Android 5. Has anybody experienced anything like this?

DebugActivity.java

package com.katasonov.everporter;



public class DebugActivity extends ActionBarActivity implements OnMapReadyCallback {

    static final String TAG = "DebugActivity";
    TextView mLogView;
    MapView mMapView;
    GoogleMap mMap;
    int mLogSize = 0;

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

        TextView versionName = (TextView) findViewById(R.id.versionName);

        try {
            PackageInfo packageInfo = getPackageManager().getPackageInfo(getPackageName(), 0);
            versionName.setText(packageInfo.versionName);
        } catch (PackageManager.NameNotFoundException e) {
            // should never happen
            throw new RuntimeException("Could not get package name: " + e);
        }

        mLogView = (TextView) findViewById(R.id.logView);
        mLogView.setMovementMethod(new ScrollingMovementMethod());
        mLogView.setFocusable(false);

        try {
            CSVReader logReader = new CSVReader(new FileReader(new File(getFilesDir(), "locations.csv")), ',');
            String [] nextLine;
            while ((nextLine = logReader.readNext()) != null) {
                // nextLine[] is an array of values from the line
                mLogView.append(StringUtils.join(nextLine, ", ") + "\n");
                mLogSize++;
            }
            logReader.close();
        } catch (IOException e) {
            Log.e(TAG, e.toString());
        }

        TextView logSize = (TextView) findViewById(R.id.logSize);
        logSize.setText(String.valueOf(mLogSize));

        // map view initialization
        mMapView = (MapView) findViewById(R.id.mapView);
        mMapView.onCreate(savedInstanceState);
        mMapView.getMapAsync(this);
    }

    // Gets to GoogleMap from the MapView and does initialization stuff
    @Override
    public void onMapReady(GoogleMap map) {
        mMap = map;

        // a list of markers
        HashMap<String, Integer> markers = new HashMap<>();
        try {
            CSVReader logReader = new CSVReader(new FileReader(new File(getFilesDir(), "locations.csv")), ',');
            String [] nextLine;
            while ((nextLine = logReader.readNext()) != null) {
                // nextLine[] is an array of values from the line
                String key = nextLine[3] + ":" + nextLine[2];
                // check if the key exists already
                if (!markers.containsKey(key)) {
                    markers.put(key, 1);
                } else {
                    Integer val = markers.get(key);
                    val++;
                    markers.put(key, val);
                }
            }
            logReader.close();
        } catch (IOException e) {
            Log.e(TAG, e.toString());
        }

        // iterate over markers and create them on the map
        Set<String> keys = markers.keySet();  //get all keys
        String[] lastLoc = null;
        double lat, lon;
        for(String key: keys) {
            String[] values = key.split(":");
            lastLoc = values;
            lat = Double.parseDouble(values[0]);
            lon = Double.parseDouble(values[1]);
            Log.d(TAG, "Creating marker for " + String.valueOf(lat) + ", " + String.valueOf(lon));
            map.addMarker(new MarkerOptions()
                    .title(markers.get(key) + " locations")
                    .position(new LatLng(lat, lon)));
        }

        map.setMyLocationEnabled(false);
        if (lastLoc != null) {
            map.moveCamera(CameraUpdateFactory.newLatLngZoom(
                    new LatLng(Double.parseDouble(lastLoc[0]), Double.parseDouble(lastLoc[1])), 13));
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mMapView.onDestroy();
    }

    @Override
    protected void onResume() {
        super.onResume();
        mMapView.onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
        mMapView.onPause();
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        mMapView.onSaveInstanceState(outState);
    }

    @Override
    public void onLowMemory() {
        super.onLowMemory();
        mMapView.onLowMemory();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_debug, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_push_log_to_server) {
            Intent serviceIntent = new Intent(this, LocationService.class);
            serviceIntent.putExtra("uploadLogFile", true);
            startService(serviceIntent);
            finish();
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}

activity_debug.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    tools:context=".DebugActivity"
    android:orientation="vertical">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:text="Version Name"
        android:id="@+id/versionName" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:text="Log Size"
        android:id="@+id/logSize" />

    <com.google.android.gms.maps.MapView android:id="@+id/mapView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/logView"
        android:enabled="true"
        android:maxLines = "25"
        android:scrollbars="vertical"
        android:scrollbarStyle="insideOverlay" />

</LinearLayout>

A piece from Logcat

03-31 17:41:23.157  15138-15138/com.katasonov.everporter I/x﹕ Making Creator dynamically
03-31 17:41:23.162  15138-15138/com.katasonov.everporter W/ResourcesManager﹕ Asset path '/system/framework/com.android.media.remotedisplay.jar' does not exist or contains no resources.
03-31 17:41:23.163  15138-15138/com.katasonov.everporter W/ResourcesManager﹕ Asset path '/system/framework/com.android.location.provider.jar' does not exist or contains no resources.
03-31 17:41:23.183  15138-15138/com.katasonov.everporter I/Google Maps Android API﹕ Google Play services client version: 6587000
03-31 17:41:23.195  15138-15138/com.katasonov.everporter I/Google Maps Android API﹕ Google Play services package version: 7099436
03-31 17:41:23.883  15138-15138/com.katasonov.everporter D/DebugActivity﹕ Creating marker for 49.22522522522522, 28.416659753499335
03-31 17:41:23.893  15138-15138/com.katasonov.everporter D/AndroidRuntime﹕ Shutting down VM
03-31 17:41:55.281  15138-15147/com.katasonov.everporter I/art﹕ Thread[5,tid=15147,WaitingInMainSignalCatcherLoop,Thread*=0xaf60e400,peer=0x32c07080,"Signal Catcher"]: reacting to signal 3
03-31 17:41:55.281  15138-15147/com.katasonov.everporter I/art﹕ [ 03-31 17:41:55.481   534:  556 I/Process  ]
    Sending signal. PID: 534 SIG: 3

Upvotes: 1

Views: 259

Answers (1)

intellion
intellion

Reputation: 1437

Okay, I'm answering my own question in less than 24h! Apparently, even though the Google Maps for Android docs say that you should do ONE of the following to make sure CameraUpdateFactory is initialized:

Prior to using any methods from this class, you must do one of the following to ensure that this class is initialized:

  • Wait for a GoogleMap to become available from a MapFragment or MapView that you have added to your application. You can verify that the GoogleMap is available by calling the getMap() method and checking that the returned object is not null.
  • Call initialize(Context). As long as a GooglePlayServicesNotAvailableException isn't thrown, this class will be correctly initialized.

the reality is that you need to do the second even if you already have a non-null GoogleMap object passed to async call onMapReady(). So when I added

MapsInitializer.initialize(this);

before

map.moveCamera

it started working as expected :) Enjoy!

Upvotes: 3

Related Questions