Reputation: 1437
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
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