Mapbox supportMapFragment / mapView is black on Android versions lower than 8 - java

I am using mapView and a SupportMapFragment to display the map in a fragment. On newer Android versions (I tested 8 and 9 on different devices) the map displays without any problem. However, on older Android versions (I tested 6 and 7) the map is showing a black screen (see black screen pic). The maps seems to work correctly though. I can click on it, routes are properly calculated an I can start navigation. So did I initialize the mapView / mapFragment wrong? How can I remove the black screen and get the mapView working on older Android versions?
I tried to initialize the mapView differently, but nothing seemed to do the trick. The map remains black. Since there is also no console output, regarding the black screen, I do not know how to proceed. Any help is greatly appreciated.
The MainActivity.java:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Mapbox.getInstance(this, getString(R.string.access_token));
setContentView(R.layout.activity_main);
(...)
// Create supportMapFragment
if (savedInstanceState == null) {
// Create fragment
final FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
// Build mapboxMap
MapboxMapOptions options = new MapboxMapOptions();
options.camera(new CameraPosition.Builder()
.target(new LatLng(-52.6885, -70.1395))
.zoom(9)
.build());
// Create map fragment
mapFragment = SupportMapFragment.newInstance(options);
// Add map fragment to parent container
transaction.add(R.id.container2, mapFragment, "com.mapbox.map");
transaction.commit();
navigationView.setCheckedItem(R.id.nav_home);
} else {
mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentByTag("com.mapbox.map");
}
mapFragment.getMapAsync(new OnMapReadyCallback() {
#Override
public void onMapReady(#NonNull MapboxMap mapboxMap) {
MainActivity.this.mapboxMap = mapboxMap;
mapView = findViewById(R.id.mapView);
(...)
#Override
protected void onStart() {
super.onStart();
mapFragment.onStart();
}
// etc.
(...)
Part of the activity_main.xml containing the mapView and the container2 for the mapFragment:
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:openDrawer="start">
<android.support.constraint.ConstraintLayout
xmlns:mapbox="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<RelativeLayout
android:id="#+id/container2"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.mapbox.mapboxsdk.maps.MapView
android:id="#+id/mapView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
(...)
I expect the mapView/fragment to show properly not only in newer Android versions, but also in older Android versions.

Related

Can't see the map from the HelloWorld example ArcGIS android SDK

I tried the Hello World code from ArcGIS android SDK and followed all the steps but the map doesn't appear and instead I get a black mapview.
Here is the java code :
package com.example.user.arcgismap;
import android.app.Activity;
import android.os.Bundle;
import com.esri.android.map.MapView;
public class MainActivity extends Activity {
MapView mMapView;
// Called when the activity is first created.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.content_main);
// After the content of this Activity is set, the map can be accessed programmatically from the layout.
mMapView = (MapView) findViewById(R.id.map);
}
#Override
protected void onPause() {
super.onPause();
// Call MapView.pause to suspend map rendering while the activity is paused, which can save battery usage.
if (mMapView != null)
{
mMapView.pause();
}
}
#Override
protected void onResume() {
super.onResume();
// Call MapView.unpause to resume map rendering when the activity returns to the foreground.
if (mMapView != null)
{
mMapView.unpause();
}
}
}
and here is the xml layout :
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context="com.example.user.arcgismap.MainActivity"
tools:showIn="#layout/activity_main">
<com.esri.android.map.MapView
android:id="#+id/map"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
mapoptions.MapType="streets"
mapoptions.center="34.056215, -117.195668,"
mapoptions.ZoomLevel="16">
</com.esri.android.map.MapView>
</RelativeLayout>
can anyone help, what am I doing wrong ?
apparently the code is working well all I had to do was to reinstall the apk and wait a little bit for the map to load. I guess patience is a virtue.

Working with Map Fragment Activity

I'm trying to create a basic activity with a google map fragment. Right now I have this:
public class MainScreen extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_screen);
// add the map fragment to the activity
if (findViewById(R.id.fragment_container) != null) {
if (savedInstanceState != null) { return; }
getSupportFragmentManager().beginTransaction()
.add(R.id.fragment_container, new FragmentGoogle()).commit();
}
}
}
public class FragmentGoogle extends android.support.v4.app.Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.map_google, container, false);
}
}
Which is producing this:
My question is: how can I interact with the fragment itself? Let's supposse I want to zoom in Sidney. Should I put the code in the MainScreen.class or in the Fragment.class? Which methods should I use? It's my first time working with fragments.
you don't need to create your own FragmentGoogle. You can use com.google.android.gms.maps.SupportMapFragment and controll it from you activity code.
in the layout:
<fragment 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:id="#+id/map"
tools:context=".MapsActivity"
android:name="com.google.android.gms.maps.SupportMapFragment" />
and then in the Activity code:
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {
private GoogleMap mMap;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
// Add a marker in Sydney, Australia, and move the camera.
LatLng sydney = new LatLng(-34, 151);
mMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));
}
}
The code is taken from
this tutorial which is enough to start and use most of the features of the Google Maps Android API, just follow the steps :)
Lets say you have an empty activity in a new project.
do this :
creating premade android map activity
And then you ll get something like this :
your project structure
go to google maps api and do what they tell you to do in the (TODO)
Create an account and a project on google maps platform https://console.cloud.google.com/google/maps-apis/
Activate android development by clicking a button you ll have to look for it
and then go to key section to create new api key
go back to android studio and click the yellow xml file in the picture
past your key there
So by now the Map actvity should give you a real map and everything should work , you should see the map if you get to the map activity
but now what you want is to add that map inside your MainActivity .(i named it ActivityMain because MapActivity and MainActivity look the same )
Now all you need to do is copy past the fragment of the xml file activity_maps.xml without changing anything except for the id .
this is the activity_main.xml :
<?xml version="1.0" encoding="utf-8"?>
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:map="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/map1"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MapsActivity" />
I tried adding a button here but i couldn't. So what i did is copy the fragment itself and put it inside the activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center"
tools:context=".ActivityMain">
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Start" />
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:map="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MapsActivity" />
</LinearLayout>
I think these are all steps to create the picture you have in your question.
I hope this was useful not painful to read .

Cannot fix Map Fragment in Fragment NullPointerException

I am trying to show a Map in a Fragment but I always get this NullPointerException:
java.lang.NullPointerException: Attempt to invoke virtual method
'com.google.android.gms.maps.GoogleMap
com.google.android.gms.maps.SupportMapFragment.getMap()' on a null
object reference
I knew there are many questions with this exception in this case but i can't find my mistake. I read any answer I have found.
Here is my Code:
public class DetailKarteFragment extends Fragment {
GoogleMap map;
static final LatLng brend = new LatLng(48.079, 8.157);
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_detail_karte, null, false);
FragmentTransaction ft = getFragmentManager().beginTransaction();
map = ((SupportMapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();
SupportMapFragment fmap = (SupportMapFragment) getFragmentManager().findFragmentById(R.id.map);
if (fmap == null) {
fmap = SupportMapFragment.newInstance();
ft.add(R.id.map, fmap);
}
ft.commit();
Marker brendMarker = map.addMarker(new MarkerOptions().position(brend).title("Brend"));
// Move the camera instantly to hamburg with a zoom of 15.
map.moveCamera(CameraUpdateFactory.newLatLngZoom(brend, 15));
// Zoom in, animating the camera.
map.animateCamera(CameraUpdateFactory.zoomTo(10), 2000, null);
return v;
}
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
}
and the xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:background="#color/background"
android:layout_height="match_parent">
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:id="#+id/map"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="bottom">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Route anzeigen"
android:id="#+id/button_route_planen"
android:layout_gravity="center_horizontal"
android:height="48dp"
android:background="#color/secondary_100"
android:layout_marginBottom="-48dp"/>
</LinearLayout>
</LinearLayout>
Just move the map = (...).getMap() line after ft.commit(). You are getting that exception because FragmentManager can't find a fragment which has not already been added or replaced into the container.
A better solution in my opinion would be:
SupportMapFragment fmap;
fmap = (SupportMapFragment) getFragmentManager().findFragmentById(R.id.map);
if (fmap == null) {
fmap = SupportMapFragment.newInstance();
ft.add(R.id.map, fmap);
ft.commit();
}
map = fmap.getMap();
You are retrieving the GoogleMap object map before checking if the SupportMapFragment even exists. I assume that this fragment hasn't been added yet, and you're invoking the getMap() method on a null reference.
I know this question is very old... But I just had this problem and I would like to share what was happening to me and the solution.
I was trying to put a MapFragment inside a fragment just like you. But I forgot to put the key in my manifest:
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="#string/google_maps_key" />
So, when this happens in a Activity, it throw an exception. That's great, because your app crashes and you can read the log and understand what you have to do! You get this message:
Caused by: java.lang.RuntimeException: API key not found.
Check that <meta-data android:name="com.google.android.geo.API_KEY" android:value="your API key"/>
is in the <application> element of AndroidManifest.xml
It's very easy to find what needs to be done this way, right?
But it doesn't happen when the MapFragment is inside another fragment!
It only return a null fragment... just like the problem you have right now.
So just put the key in the Manifest and you will be fine! I hope Google fix this, because it took me some hours to find out what was wrong.

OnClick doesn't work with LinearLayout

OnClick doesn't work. Nothing happens after clicking on layout. It seems like it is clickable, because layout changes its color, but new layout doesn't open.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/window"
android:layout_width="295dp"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="#drawable/editborder"
android:clickable="true"
android:onClick="openBigImage">
Here is more code for Main Activity:
public class MyMapActivity extends FragmentActivity implements LocationListener
{
private Marker marker;
private Hashtable<String, String> markers;
private ImageLoader imageLoader;
private DisplayImageOptions options;
private GoogleMap map;
private ListView mainListView ;
private ArrayAdapter<String> listAdapter ;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_map);
// Look up the AdView as a resource and load a request.
//AdView adView = (AdView)this.findViewById(R.id.adView);
//adView.loadAd(new AdRequest());
// Getting Google Play availability status
int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getBaseContext());
// Showing status
if(status!=ConnectionResult.SUCCESS)
{ // Google Play Services are not available
int requestCode = 10;
Dialog dialog = GooglePlayServicesUtil.getErrorDialog(status, this, requestCode);
dialog.show();
}
else
{// Google Play Services are available
// Getting reference to the SupportMapFragment of activity_main.xml
SupportMapFragment mapFragment = (SupportMapFragment)getSupportFragmentManager().findFragmentById(R.id.map);
if (savedInstanceState == null) {
// First incarnation of this activity.
mapFragment.setRetainInstance(true);
}
else
{
// Reincarnated activity. The obtained map is the same map instance in the previous
// activity life cycle. There is no need to reinitialize it.
map = mapFragment.getMap();
}
setUpMapIfNeeded();
}
}
#Override
protected void onResume()
{
super.onResume();
setUpMapIfNeeded();
}
public void openBigImage(View v)
{
setContentView(R.layout.bigpicture);
}
bigpicture.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/bigpicture"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000000"
android:orientation="vertical">
<fragment
android:id="#+id/minimap"
android:layout_width="200px"
android:layout_height="200px"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
class="com.google.android.gms.maps.SupportMapFragment" />
<ImageView
android:id="#+id/badge"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:adjustViewBounds="true" />
</RelativeLayout>
Calling setContentView() multiple times worked in other cases, like menu items "about", "settings" etc.
Tried to make without setContentView. I've put new Layout to the main.xml and made visibility GONE. OnClick method should change visibility to visible, but again nothing happens.
Logcat says "11-25 13:47:28.638: D/GestureDetector(3156): [Surface Touch Event] mSweepDown False, mLRSDCnt : -1 mTouchCnt : 2 mFalseSizeCnt:0" when i'm clicking on linear layout.
Paul,
One thing is close the linear layout with /> .I am assuming that you have followed the map tutorials link and passed all the manifest permissions and other requirements. You might have some reasons to use px. Check if map is being created. Also give some height and background color to your badge image and see if something happens.
I tested your code without map fragment and it worked fine.
Can you post the error log ?
Found. It is a click on InfoWindow, so we should implement onInfoWindowClick.
But first we must add map.setOnInfoWindowClickListener(this); in main activity. Main activity must implement OnInfoWindowClickListener.
I've added new LinearLayout to the main.xml, made it invisible.
Here's code for onInfoWindowClick:
#Override
public void onInfoWindowClick(Marker marker) {
LinearLayout secondLL = (LinearLayout) findViewById(R.id.bigpicture);
int visibility = secondLL.getVisibility();
if(visibility == View.GONE)
{
secondLL.setVisibility(View.VISIBLE);
}
}
I think you can't use onClick attribute.
You have to use setOnClickListener() like that :
LinearLayout layout = (LinearLayout )findViewById(R.id.window);
layout .setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
YourActivity.this.setContentView(R.layout.bigpicture);
}
});

Android Sliding Menu does not work on tablets; Menu is acting as if in normal handset (slide on button click)

I'm using jfeinstein10 - SlidingMenu. I have already implemented it using a normal handset but when I try my application in a tablet, it still shows the slide button. I followed the tutorial at ResponsiveUI but my menu is still hiding. I want it to be permanently shown when I am using a tablet. Shouldn't be menu_frame.xml automatically be called when using tablets? I tried commenting the part where it ask if menu_frame is null to force it to act in my tablet, but an error shows the menu_frame is not found. I'm confused at how sliding menu really works. Please help! Any idea why is it acting like that in tablet? Here are my source codes:
BaseActivity.java
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getSupportActionBar().hide();
setContentView(R.layout.activity_base);
// check if the content frame contains the menu frame
if (findViewById(R.id.menu_frame) == null) {
setBehindContentView(R.layout.menu_frame);
getSlidingMenu().setMode(SlidingMenu.LEFT);
getSlidingMenu().setSlidingEnabled(true);
getSlidingMenu().setTouchModeAbove(SlidingMenu.TOUCHMODE_MARGIN);
getSlidingMenu().setBehindWidthRes(R.dimen.sidebar_default_width);
} else {
// add a dummy view
Log.v("BaseActivity", "menu not null");
View v = new View(this);
setBehindContentView(v);
getSlidingMenu().setSlidingEnabled(false);
getSlidingMenu().setTouchModeAbove(SlidingMenu.TOUCHMODE_NONE);
getSlidingMenu().setBehindWidthRes(R.dimen.sidebar_no_width);
}
// set the Above View Fragment
if (savedInstanceState != null) {
mContent = getSupportFragmentManager().getFragment(savedInstanceState, "mContent");
mMenuPosition = savedInstanceState.getInt("menu_position");
}
if (mContent == null) {
mContent = new BirdsFragment();
mMenuPosition = 0;
}
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.content_frame, mContent)
.commit();
// set the Behind View Fragment
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.menu_frame, new MenuListFragment())
.commit();
// customize the SlidingMenu
SlidingMenu sm = getSlidingMenu();
sm.setShadowWidthRes(R.dimen.shadow_width);
sm.setShadowDrawable(R.drawable.shadow);
sm.setBehindOffsetRes(R.dimen.slidingmenu_offset);
sm.setFadeDegree(0.35f);
}
layout/activity_base.xml
<RelativeLayout 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"
tools:context=".BaseActivity">
<include layout="#layout/actionbar" />
<FrameLayout
android:id="#+id/content_frame"
android:layout_below="#id/actionbar"
android:layout_width="match_parent"
android:layout_height="match_parent" />
layout/menu_frame.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/menu_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" />
I finally got the answer. Of course menu_frame can not just be added magically; You have to setup your xml at layout-large and layout-large-land for the menu_frame to appear at a tablet.

Categories