implement mapview version 1 inside fragment? - android

Is there a way to implement mapview version 1 inside fragment?
I tried sth like:
MainActivity:
public class MainActivity extends FragmentActivity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
Then, I want 2 fragments . One that has the mapview and second which will have a textview in which the location will be shown.
I can't implement the first fragment.I can't figure how to implement the map.I mean , for the mapview to work it needs "extends MapActivity" but I need "extends fragment".
Also , in main.xml how to do it?I tried :
<fragment
class="com.google.android.maps.MapView"
android:name="com.example.....MapClass" //is this right?but it is necessary for fragment?
android:id="#+id/fragment1"
android:layout_weight="1"
android:layout_width="0px"
android:layout_height="match_parent"
android:apiKey="mykey" />
<fragment
class="com.example...getloclass"
android:id="#+id/fragment2"
android:layout_weight="1"
android:layout_width="0px"
android:layout_height="match_parent" />

From here https://developers.google.com/maps/documentation/android/v1/hello-mapview, you can see that
Version 1 of the Google Maps Android API as been officially deprecated
as of December 3rd, 2012
So you shouldn't use MapView anymore. I suggest you use a MapFragment instead. See the excellent documentation for it here: https://developers.google.com/maps/documentation/android/reference/com/google/android/gms/maps/MapFragment

Related

Google Map turns (partly) black when transitioning to Google Maps app

Description
When starting the Google Maps app (using a "get directions" Intent) from within my own app, part or all of the map presented in my app sometimes (~25-50% of the time) turns black during the screen transition. Here are videos from a minimal working example:
Real device
A rectangular piece of the map that is covered by a transparent view turns black during the transition. Note that while the transparent part of the view is unnecessary in this MWE, it is a required part of my actual application.
Emulator
The entire map turns black during the transition.
The Activity shown has the following layout:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.gms.maps.MapView
android:id="#+id/map_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<FrameLayout
android:id="#+id/bottom_sheet"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="150dp"
android:layout_marginTop="48dp"
android:background="#android:color/white" />
<Button
android:id="#+id/button_action"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_gravity="center" />
</FrameLayout>
</RelativeLayout>
and code:
public class MapsActivity extends AppCompatActivity {
private MapView mapView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
findViewById(R.id.button_action).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(final View view) {
final Intent intent = new Intent(ACTION_VIEW, Uri.parse("google.navigation:q=42.3314,-83.0458"));
intent.setPackage("com.google.android.apps.maps");
startActivity(intent);
}
});
mapView = (MapView) findViewById(R.id.map_view);
mapView.onCreate(savedInstanceState);
}
// All the other overridden lifecycle methods, forwarded to mapView correctly.
}
The project uses the latest version of Google Play Services (10.0.1). Full code is available on GitHub.
I've read through a bunch of legacy issues with maps turning black, but those seem to relate to a single map being scrolled (e.g. https://code.google.com/p/gmaps-api-issues/issues/detail?id=4659).
I don't have a reliable way to reproduce the issue, even within the MWE, but it happens often enough to be easy to observe and capture.
Device specs seem to make a difference (higher spec devices exhibit the issue less often).
Questions
What's the underlying cause of this issue?
Is there something I should (or should not) be doing to avoid this ugly behavior when launching the Google Maps app?

Google map fragment is null?

I am trying to embed Google map in Activity. I integrated it a couple of times before but It's not happening right now.
My layout file:
<fragment
android:id="#+id/location_map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="right|center_vertical" />
Map Class
#EActivity(R.layout.location_activity)
public class FIndLocationActivity extends AppCompatActivity implements OnMapReadyCallback {
#AfterExtras
void afterViewCreated() {
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.location_map);
mapFragment.getMapAsync(this);
.....
.....
}
}
mapFragment remains always Null. What am I doing wrong here? I also followed this tutorial but still it's throwing null. I am using actual device to test the app.
Check if you added all credentials for GMaps in your app, including additional egl 'uses' lines in manifest. This may be the issue why system can't create fragment.

Using Google Maps v2 in subclass activity with navigation drawer

I need to work back to API level 8. I have multiple activities and am using a navigation drawer to move between them as well as an action bar (with AppCompat v7). I have created a base abstract class that has all the navigation drawer setup and handling and that descends from ActionBarActivity.
File BaseNavActivity.java
abstract class BaseNavActivity extends ActionBarActivity {
}
All my activities subclass BaseNavActivity, and they all work fine.
public class MainActivity extends BaseNavActivity {
}
Before I added the navigation drawer feature I had a map working fine when descending from FragmentActivity. However, I cannot do that anymore because I need to descend from my BaseNavActivity. Even though the docs say ActionBarActivity descends from FragmentActivity I get an error when trying to use this XML.
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/drawerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/background" >
<!-- The main content view -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/background"
android:orientation="vertical"
>
<include layout="#layout/common_toolbar" />
<fragment
android:id="#+id/map"
class="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="3dip"
/>
<include layout="#layout/common_footer" />
</LinearLayout>
<!-- The navigation drawer -->
<include layout="#layout/nav_menu" />
</android.support.v4.widget.DrawerLayout>
I get an InflateException: Binary XML file line #19: Error inflating class fragment.
I have tried other solutions such as having a separate XML file with just the and opening it as a fragment and adding it to the above in place of the . That approach always returned a null when I tried to point to the map (smf was always null):
SupportMapFragment smf = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
I also tried to have a
public class MapFragment extends FragmentActivity {
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
View myFragmentView = inflater.inflate(R.layout.location_map, container, false);
return myFragmentView;
}
}
but I couldn't add the fragment using
MapFragment mapFragment = new MapFragment();
fragmentTransaction.add(R.id.map_container, mapFragment);
fragmentTransaction.commit();
The add() function needed to have parameters of (int, Fragment).
Any help will be appreciated. If you need more code I can add it but didn't want to make this post too long. I have spent a couple of days searching and trying various approaches and nothing seems to get everything working together.
Basically I would like to know how to have a <fragment> inside the XML when descending from a custom subclass that descends from ActionBarActivity. My 2nd choice would be to know how to add a fragment that holds the map and works with the support libraries.
Thanks!
I finally found my issue. I took a different approach for searching and found this gem: Android Google Maps V2 Caused by: java.lang.ClassCastException: com.google.android.gms.maps.SupportMapFragment cannot be cast to android.app.Fragment
Basically my issue was that I had the custom base class call setContentView before calling the super.onCreate. That meant that fragments weren't understood because it was a couple of supers up that knew about them. This caught me because 1) I needed to specify a theme that appcompat could use and had my setContentView next to it when I copied things to the base class, and 2) everything else worked up to this point so I didn't realize it was incorrect.
So the fix is in my base class that all my activities inherit from (abbreviated):
abstract class BaseNavActivity extends ActionBarActivity {
protected void onCreate(Bundle savedInstanceState, int resLayout) {
// need to set the theme first
setTheme(R.style.AppTheme2);
// then call super before setting the content view
super.onCreate(savedInstanceState);
setContentView(resLayout);
}
}

Google map in separate activity resulting in: java.lang.IllegalStateException: Could not execute method of the activity

Im having some trouble accessing Hello Mapview at the moment, http://developer.android.com/training/tutorials/views/hello-mapview.html, but i think ive done this correctly. I want to show a map in a separate activity.
Map.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<com.google.android.maps.MapView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/mapview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:clickable="true"
android:apiKey="working key"
/>
</LinearLayout>
Button onclick event that should show my map
public void showMap(View v){
Intent intent = new Intent(getBaseContext(), GoogleMapsActivity.class);
startActivity(intent);
}
GoogleMapsActivity.java
public class GoogleMapsActivity extends MapActivity
{
MapView mapView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.map);
mapView = (MapView) findViewById(R.id.mapview);
mapView.setBuiltInZoomControls(true);
}
The activity is added to my manifest, Google apis is included etc. Its working if i put the map in my main activity, but not in my GoogleMapsActivity. Please tell me what ive missed here.
Thanks
From https://developers.google.com/maps/documentation/android/reference/:
Only one MapActivity is supported per process. Multiple MapActivities running simultaneously are likely to interfere in unexpected and undesired ways.
Basically, you can only have 1 MapActivity, and MapViews can only be hosted in a MapActivity. What you want basically isn't possible.
EDIT: not sure it would work for you, but you might try marking your second activity with android:process=":remote" and see if that works, but I doubt it.
EDIT: there is evidently some confusion. Look at https://developers.google.com/maps/documentation/android/reference/com/google/android/maps/MapView. This states that:
A MapView can only be constructed (or inflated) by a MapActivity. This is because it depends on threads which access the network and filesystem in the background; these threads must be shepherded by the lifecycle management in MapActivity. Tiles are cached on the filesystem in your application's directory. The cache is auto-managed so you don't need to do anything with it, and can delete it at any time.
I'll re-iterate: You CAN'T display a MapView in any other activity.
The problem was a misspelling in my manifest file,
<activity android:name=".GoogleMapActivity" /> //missing an "s"

Speed up launch of activity containing mapview and extends MapviewActivity

I have an app which contains an activity which is a MapviewActivity and is mostly a mapview.
However I have noticed that the start up time of the activity is really slow and causes a lag from the moment the button is pressed to go in to the map activity. I feel this creates a bad user experience and would like to avoid this.
I have already set the background of the map activity to #null as suggested by one of the UI improvement articles on googles developer page, which I feel does not do the trick.
Is there a way to improve this? I would not like the main home screen to get stuck on the launch of the activity, even a transfer to the map activity and then loading the mapview would be better.
Thanks,
Jason
You could try removing the MapView from your layout. Then, in onCreate(), use post() to schedule a Runnable to add in the MapView and do your map-related initialization from Java. By using post() (or, potentially, postDelayed()) to postpone the MapView further, you should be able to render the rest of the activity first.
I haven't tried this, so YMMV. :-)
This has been bugging me for a while and I worked this out by expanding on on CommonsWare's answer:
I am currently using this solution that sped up my Activity loading time greatly and make everything look as smooth as it gets.
My MapActivity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_map); // See activity_map.xml below.
// Start a runnable that does the entire Map setup.
// A delay does not seem to be necessary.
Handler mapSetupHandler = new Handler();
Runnable mapSetupRunnable = new Runnable() {
public void run() {
FragmentManager fragMan = getSupportFragmentManager();
FragmentTransaction fragTransaction = fragMan.beginTransaction();
final SupportMapFragment mapFragment = new SupportMapFragment();
fragTransaction.add(R.id.container_map, mapFragment, "mapFragment");
fragTransaction.commit();
// At the end, retrieve the GoogleMap object and the View for further setup,
// zoom in on a region, add markers etc.
mapFragment.getMapAsync(new OnMapReadyCallback() {
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
mMapView = mapFragment.getView();
setUpMap();
}
});
}
};
mapSetupHandler.post(mapSetupRunnable);
}
layout/activity_map.xml:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!--This FrameLayout will be used by the GoogleMap-->
<!--as a container for the SupportMapFragment.-->
<FrameLayout
android:id="#+id/container_map"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_above="#id/bar_room_password"
android:layout_below="#id/toolbar">
<!--Initially the container is filled with a placeholder image.-->
<!--A small, heavily blurred image of a map screenshot is used-->
<!--in order to fake a loading map.-->
<ImageView
android:id="#+id/image_map_placeholder"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:alpha="50"
android:contentDescription="#string/map"
android:scaleType="centerCrop"
android:src="#drawable/placeholder_map" />
</FrameLayout>
[... more, unrelated Views...]
</RelativeLayout>
The Activity appears quickly because the setup is handled inside of a Runnable. Also, instead of just showing an empty View while the GoogleMap is doing its setup and downloads, I show a vague fake image of a map.
The Google logo is being placed on top of the ImageView relatively early so it looks pretty convincing with just a 128x128 pixel image:
I tried CommonsWare's answer, but there was a significantly delay launching even a bare MapActivity without a MapView in it.
So, I put another activity in the middle, "MapLoading". My home activity launches MapLoading, which then uses post() to immediately launch the MapActivity. Because of the lag, the app sticks on MapLoading for a few seconds (which is the intended result, as opposed to sticking on my home activity).
The MapLoading activity has noHistory set so when the back button is clicked from the MapActivity it goes right through to the home screen. Future launches of the MapActivity are very fast and the MapLoading activity just flashes on the screen.
Here is the code for MapLoading (the activity with the MapView in it is called Map):
public class MapLoading extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.maploading);
new Handler().post(new Runnable() {
public void run()
{
startActivity(new Intent(MapLoading.this, Map.class));
}
});
}
}
Here is its layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="#+id/maploading"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center"
android:textSize="14pt"
android:text="Loading map..."
/>
</RelativeLayout>
And the corresponding stanza in AndroidManifest.xml:
<activity android:label="#string/app_name"
android:name="MapLoading"
android:noHistory="true" />

Categories

Resources