android - picasso not rendering image in first load of fragment - google-maps

I'm using Picasso library to load image from URL to be rendered in a Google Map Cluster Marker, the problem is on the first load of the Fragment the images is not displaying I have to reload the Fragment for the images to display.
MapsFragment
private ClusterManager mClusterManager;
private ClusterManagerRenderer mClusterManagerRenderer;
private ArrayList<ClusterMarker> mClusterMarkers = new ArrayList<>();
//....
public void onMapReady(GoogleMap googleMap) {
if (ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) return;
//....
mMap = googleMap;
renderMarkers();
setGoogleMapStyle();
//.....
}
private void renderMarkers(){
//.....
if (mClusterManager != null && !mClusterMarkers.isEmpty()) {
mClusterManager.clearItems();
mClusterMarkers.clear();
}
if(mMap != null) {
if(mClusterManager == null) mClusterManager = new ClusterManager<ClusterMarker>(getActivity().getApplicationContext(), mMap);
if(mClusterManagerRenderer == null){
mClusterManagerRenderer = new ClusterManagerRenderer(
getContext(),
mMap,
mClusterManager
);
mClusterManager.setRenderer(mClusterManagerRenderer);
}
try{
ClusterMarker newClusterMarker = new ClusterMarker(
new LatLng((Double) eachImage.get("lat"), (Double) eachImage.get("lng")), // image lat lng
(String) eachImage.get("notes"), // marker title
(String) eachImage.get("notes"), // marker snippet
(String) eachImage.get("image") // image url http://i.imgur.com/DvpvklR.png
);
mClusterManager.addItem(newClusterMarker);
mClusterMarkers.add(newClusterMarker);
}catch (NullPointerException e){
Log.e("tag", "addMapMarkers: NullPointerException: " + e.getMessage() );
}
mClusterManager.cluster();
}
//....
Log.e("tag", "addMapMarkers: markers are set");
}
ClusterManagerRenderer
public class ClusterManagerRenderer extends DefaultClusterRenderer<ClusterMarker> {
//....
#Override
protected void onBeforeClusterItemRendered(ClusterMarker item, MarkerOptions markerOptions) {
Picasso.get().load(item.getThumbnail()).into(imageView);
Bitmap icon = iconGenerator.makeIcon();
markerOptions.icon(BitmapDescriptorFactory.fromBitmap(icon)).title(item.getTitle());
}
//....
}

Related

NullPointerException at dual fragment display

I'm writing an app that has two kinds of displays:
1. "phone mode" on normal sized displays, show one fragment at a time (search fragment, map fragment, etc). Here the fragments load with no particular problem.
2."Tablet mode" on larger displays, shows two fragments side by side - one is the same as "phone mode", the second is a permenant display of the map fragment. When trying to load the app on a tablet emulator it throws an exception:
FATAL EXCEPTION: main
Process: il.co.sredizemnomorie.myapiplaces, PID: 7808
java.lang.RuntimeException: Unable to start activity ComponentInfo{il.co.sredizemnomorie.myapiplaces/il.co.sredizemnomorie.myapiplaces.MainActivity}: java.lang.NullPointerException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2195)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
at android.app.ActivityThread.access$800(ActivityThread.java:135)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5017)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at maps.f.g.a(Unknown Source)
at maps.ag.g$a.<init>(Unknown Source)
at maps.ag.g.a(Unknown Source)
at maps.ag.R.<init>(Unknown Source)
at maps.ag.t.a(Unknown Source)
at uz.onTransact(:com.google.android.gms.DynamiteModulesB:167)
at android.os.Binder.transact(Binder.java:361)
at com.google.android.gms.maps.internal.IGoogleMapDelegate$zza$zza.addMarker(Unknown Source)
at com.google.android.gms.maps.GoogleMap.addMarker(Unknown Source)
at il.co.sredizemnomorie.myapiplaces.FragmentWithMap.setUpMap(FragmentWithMap.java:165)
at il.co.sredizemnomorie.myapiplaces.FragmentWithMap.setUpMapIfNeeded(FragmentWithMap.java:141)
at il.co.sredizemnomorie.myapiplaces.FragmentWithMap.onCreateView(FragmentWithMap.java:72)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:1974)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1067)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1252)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:742)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1617)
at android.support.v4.app.FragmentController.execPendingActions(FragmentController.java:339)
at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:602)
at il.co.sredizemnomorie.myapiplaces.MainActivity.onStart(MainActivity.java:270)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1171)
at android.app.Activity.performStart(Activity.java:5241)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2168)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245) 
at android.app.ActivityThread.access$800(ActivityThread.java:135) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:136) 
at android.app.ActivityThread.main(ActivityThread.java:5017) 
at java.lang.reflect.Method.invokeNative(Native Method) 
at java.lang.reflect.Method.invoke(Method.java:515) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595) 
at dalvik.system.NativeStart.main(Native Method) 
Here's the code:
MainActivity.java
public class MainActivity extends ActionBarActivity implements FragmentWithDetails.OnFragmentInteractionListener, FragmentWithMap.OnFragmentInteractionListener,
FragmentWithDetails.ListFragmentListener, TextView.OnEditorActionListener, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener,
SettingsFragment.OnFragmentInteractionListener {
private static final String TAG = "PlaceFounder";
public static final String TAG_FAVORITES = "frag_favorites";
private static final String TAG_MAP = "map";
private static final String TAG_DETAILS = "details";
protected GoogleApiClient mGoogleApiClient;
protected Location mLastLocation;
private Bundle currentLocationBundle = new Bundle();
FragmentTransaction fragmentTransaction;
private android.support.v4.app.FragmentManager fragmentManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
buildGoogleApiClient();
fragmentManager = getSupportFragmentManager();
FragmentWithDetails fragmentDetails;
if (isSingleFragment()) {
if (savedInstanceState == null) {
fragmentDetails = FragmentWithDetails.newInstance();
fragmentDetails.setArguments(currentLocationBundle);
fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.add(R.id.fragmnet_container, fragmentDetails, TAG_DETAILS);
fragmentTransaction.commit();
}
}//end if we at small screen
else {
if (savedInstanceState == null) {
fragmentDetails = FragmentWithDetails.newInstance();
FragmentWithMap fragmentWithMap = FragmentWithMap.newInstance(null);
fragmentDetails.setArguments(currentLocationBundle);
fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.add(R.id.fragmnet_container_details, fragmentDetails, TAG_DETAILS);
fragmentTransaction.add(R.id.fragmnet_container_map, fragmentWithMap, TAG_MAP);
fragmentTransaction.commit();
}
}//end if big screen
}
// Show favorites fragment
private void showFavorites() {
currentLocationBundle.putInt("isShowFav", 1);
FragmentWithDetails fragmentFavorites = (FragmentWithDetails) fragmentManager.findFragmentByTag(TAG_FAVORITES);
if (fragmentFavorites == null) {
fragmentFavorites = FragmentWithDetails.newInstance();
fragmentFavorites.setArguments(currentLocationBundle);
}
fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fragmnet_container, fragmentFavorites, TAG_FAVORITES);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.show(fragmentFavorites);
handleLargeLayout();
fragmentTransaction.commit();
}
//Hide details and map only on large screen
//On small screen we reuse the same container
private void handleLargeLayout() {
if (!isSingleFragment()) {
fragmentTransaction.hide(getDetailsFragment());
fragmentTransaction.hide(getMapFragment());
}
}
private FragmentWithMap getMapFragment() {
return (FragmentWithMap) fragmentManager.findFragmentByTag(TAG_MAP);
}
private FragmentWithDetails getDetailsFragment() {
return (FragmentWithDetails) fragmentManager.findFragmentByTag(TAG_DETAILS);
}
private FragmentWithDetails getFavoritesFragment() {
return (FragmentWithDetails) fragmentManager.findFragmentByTag(TAG_FAVORITES);
}
// Show settings fragment
private void showSettings() {
SettingsFragment settingsFragment = SettingsFragment.newInstance();
fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fragmnet_container, settingsFragment, "frag_settings");
fragmentTransaction.addToBackStack(null);
fragmentTransaction.show(settingsFragment);
handleLargeLayout();
fragmentTransaction.commit();
}
// Display current location on map
private void getCurrentLocation() {
String currentLat = null;
String currentLong = null;
if (mLastLocation != null) {
currentLat = String.valueOf(mLastLocation.getLatitude());
currentLong = String.valueOf(mLastLocation.getLongitude());
if (getMapFragment() != null) {
getMapFragment().setPlace(new Place(0, "Current location", "", (float) mLastLocation.getLatitude(), (float) mLastLocation.getLongitude()));
}
}
currentLocationBundle.putString("currentLat", currentLat);
currentLocationBundle.putString("currentLong", currentLong);
}
//Builds a GoogleApiClient.
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_settings:
showSettings();
return true;
case R.id.action_favorites:
showFavorites();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
protected boolean isSingleFragment() {
return findViewById(R.id.layout_single_fragment) != null;
}
#Override
public void onFragmentInteraction(Uri uri) {
}
#Override
public void onPlaceSelected(long placeId) {
fragmentManager = getSupportFragmentManager();
Place place = getPlace(placeId);
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
if (isSingleFragment()) {
FragmentWithMap fragmentWithMap = FragmentWithMap.newInstance(place);
fragmentTransaction.replace(R.id.fragmnet_container, fragmentWithMap, TAG_MAP).addToBackStack(null);
} else {
if (getMapFragment() == null) {
android.support.v4.app.Fragment fragmentWithMap = FragmentWithMap.newInstance(place);
fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.add(R.id.fragmnet_container_map, fragmentWithMap, TAG_MAP);
fragmentTransaction.show(fragmentWithMap);
fragmentTransaction.show(getDetailsFragment());
} else {
FragmentWithMap fragmentWithMap = getMapFragment();
fragmentTransaction.show(fragmentWithMap);
fragmentTransaction.show(getDetailsFragment());
if (getFavoritesFragment() != null) {
fragmentTransaction.hide(getFavoritesFragment());
}
fragmentWithMap.showPlace(place);
}
}
fragmentTransaction.commit();
}
private Place getPlace(long placeId) {
Cursor cursor = null;
Place place = null;
try {
cursor = getContentResolver().query(PlacesContract.Places.CONTENT_URI, null, "_id=" + placeId, null, "name DESC");
cursor.moveToNext();
place = new Place(cursor.getInt(0), cursor.getString(1), cursor.getString(2), cursor.getFloat(3), cursor.getFloat(4));
} finally {
if (cursor != null && !cursor.isClosed()) {
cursor.close();
}
}
return place;
}
#Override
public void onBackPressed() {
if (isSingleFragment() && getMapFragment() != null) {
fragmentManager.popBackStack(null,
FragmentManager.POP_BACK_STACK_INCLUSIVE);
} else if (fragmentManager.findFragmentByTag("frag_favorites") != null) {
fragmentManager.popBackStack(null,
FragmentManager.POP_BACK_STACK_INCLUSIVE);
} else if (fragmentManager.findFragmentByTag("frag_settings") != null) {
fragmentManager.popBackStack(null,
FragmentManager.POP_BACK_STACK_INCLUSIVE);
} else {
super.onBackPressed();
}
}
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
return true;
}
#Override
protected void onStart() {
super.onStart();
mGoogleApiClient.connect();
//start google analytics
EasyTracker.getInstance(this).activityStart(this); // Add this method.
}
#Override
protected void onStop() {
super.onStop();
if (mGoogleApiClient.isConnected()) {
mGoogleApiClient.disconnect();
}
//stop google analytics
EasyTracker.getInstance(this).activityStop(this); // Add this method.
}
/**
* Runs when a GoogleApiClient object successfully connects.
*/
#Override
public void onConnected(Bundle connectionHint) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (mLastLocation == null) {
Toast.makeText(this, "Location not found", Toast.LENGTH_LONG).show();
}
getCurrentLocation();
}
#Override
public void onConnectionFailed(ConnectionResult result) {
toast("No Google Service");
Log.i(TAG, "Connection failed: ConnectionResult.getErrorCode() = " + result.getErrorCode());
}
private void toast(String message) {
Toast.makeText(this, message,
Toast.LENGTH_LONG).show();
}
#Override
public void onConnectionSuspended(int cause) {
// The connection to Google Play services was lost for some reason
Log.i(TAG, "Connection suspended");
mGoogleApiClient.connect();
}
}
the map fragment:
FragmentWithMap.java
public class FragmentWithMap extends android.support.v4.app.Fragment {
private OnFragmentInteractionListener mListener;
private static final double LAT = 32.084;
private static final double LON = 34.8878;
Place place;
private GoogleMap mMap;
private View view;
private Marker marker;
int userIcon = FragmentWithDetails.userIcon;
public static FragmentWithMap newInstance(Place place) {
Bundle args = new Bundle();
if (place != null) {
args.putInt("id", place.getId());
args.putString("name", place.getName());
args.putString("address", place.getAddress());
args.putFloat("lat", place.getLat());
args.putFloat("lng", place.getLng());
}
FragmentWithMap fragment = new FragmentWithMap();
fragment.setArguments(args);
return fragment;
}
public FragmentWithMap() {
//empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null && getArguments().getString("name") != null) {
place = new Place(getArguments().getInt("id"), getArguments().getString("name"),
getArguments().getString("address"), getArguments().getFloat("lat"),
getArguments().getFloat("lng"));
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if (view == null) {
view = inflater.inflate(R.layout.fragment_fragment_with_map, container, false);
}
setUpMapIfNeeded();
return view;
}
#Override
public void onDestroyView() {
super.onDestroyView();
android.support.v4.app.Fragment f = getFragmentManager()
.findFragmentById(R.id.fragmnet_container_map);
if (f != null) {
try {
getFragmentManager().beginTransaction().remove(f).commit();
} catch (IllegalStateException ise) {
Log.d("FragmentWithMap", "Already closed");
}
}
ViewGroup parentViewGroup = (ViewGroup) view.getParent();
if (parentViewGroup != null) {
parentViewGroup.removeAllViews();
}
}
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mListener = (OnFragmentInteractionListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnFragmentInteractionListener");
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
public void showPlace(Place place) {
setPlace(place);
setUpMap();
}
public void setPlace(Place place) {
this.place = place;
}
public interface OnFragmentInteractionListener {
public void onFragmentInteraction(Uri uri);
}
private void setUpMapIfNeeded() {
// Do a null check
if (mMap == null) {
// Try to obtain the map from the SupportMapFragment.
Fragment mmm = getChildFragmentManager().findFragmentById(R.id.fragment_map2);
mMap = ((SupportMapFragment) mmm).getMap();
// Check if we were successful
if (mMap != null) {
setUpMap();
}
}
}
private void setUpMap() {
double lat = LAT;
double lng = LON;
String name = "You are here";
if (place != null) {
lat = place.getLat();
lng = place.getLng();
name = place.getName();
}
if (marker != null) {
marker.remove();
}
LatLng position = new LatLng(lat, lng);
MarkerOptions markerOptions = new MarkerOptions().
position(position).
title(name).
icon(BitmapDescriptorFactory.fromResource(userIcon)).
snippet("Your last recorded location");
marker = mMap.addMarker(markerOptions);
if (ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
mMap.setMyLocationEnabled(true);
CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(position, 15);
mMap.animateCamera(cameraUpdate);
}
}
The XMLs:
activity_main.xml
"phone mode":
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/layout_single_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/darker_gray"
android:paddingBottom="16dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingTop="16dp"
tools:context=".MainActivity">
<FrameLayout
android:id="#+id/fragmnet_container"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"></FrameLayout>
and "tablet mode"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/layout_two_fragments"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/darker_gray"
android:paddingBottom="16dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingTop="16dp"
tools:context=".MainActivity"
>
<FrameLayout
android:id="#+id/fragmnet_container"
android:layout_width="wrap_content"
android:layout_height="match_parent"></FrameLayout>
<FrameLayout
android:id="#+id/fragmnet_container_details"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1.31"></FrameLayout>
<FrameLayout
android:id="#+id/fragmnet_container_map"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2"></FrameLayout>
I'd greatly appreciate any help you might offer...
Update:
The crashpoint is at the end of the mapfragment in the at the marker = mMap.addMarker(markerOptions); line. I guess I must not be handling the markers correctly... Still not clear why it works fine in single fragment mode, and not dual fragments.
You are trying to access UI elements in the onCreate() but , onCreate() is too early to call getView() and it will return null. Postpone the code that needs to touch the fragment's view hierarchy to onCreateView() or later in the fragment lifecycle. Since in fragment views can be created in onCreateView() method.
Try to include onActivityCreated() which calls when the fragment's activity has been created and this fragment view hierarchy instantiated.
Update: solved
The problem ended up being with the userIcon (which represents the cosmetic type of marker shown on the map). When the app first load, it for some reason returned 0 instead of null. Since it's merely a cosmetic feature I simply removed, and that solved the problem. Not the prettiest solution but it's the one I got, since time constraint prevent me from dedicated more time to this when more critical parts of the app still need tending; I hope it helps. I hope a more experienced programmer will likely be familiar enough with the marker system to offer alternative solutions/workarounds for those who wish to include custom markers.

Xamarin Forms - Highlight route for WinPhone 8.1 part

Since a long time, I'm trying to make work a polyline for crossplateform using.
I did it and it works well, I followed the Map Control tutorial in first, and then Highlight a Route on a Map tutorial.
I then update the code to make it reloads if a any changes comes, however, I'm getting an issue and I couldn't figure it out... It does works for Android & iOS.
polyline.Path = new Geopath(coordinates); throws Catastrophic failure (Exception from HRESULT: 0x8000FFFF (E_UNEXPECTED))
The problem is that my two others renderer (Android & iOS) works.. Maybe something isn't possible because I work with WinPhone8.1 unlike the tutorial, which is UWP.
public class CustomMapRenderer : MapRenderer
{
MapControl nativeMap;
CustomMap formsMap;
protected override void OnElementChanged(ElementChangedEventArgs<Map> e)
{
base.OnElementChanged(e);
if (e.OldElement != null)
{
nativeMap = Control as MapControl;
}
if (e.NewElement != null)
{
formsMap = (CustomMap)e.NewElement;
nativeMap = Control as MapControl;
UpdatePolyLine();
}
}
protected override void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (this.Element == null || this.Control == null)
return;
if (e.PropertyName == CustomMap.RouteCoordinatesProperty.PropertyName)
{
UpdatePolyLine();
}
}
private void UpdatePolyLine()
{
if (nativeMap != null)
{
var coordinates = new List<BasicGeoposition>();
foreach (var position in formsMap.RouteCoordinates)
{
coordinates.Add(new BasicGeoposition() { Latitude = position.Latitude, Longitude = position.Longitude });
}
var polyline = new MapPolyline();
polyline.StrokeColor = Color.FromArgb(128, 255, 0, 0);
polyline.StrokeThickness = 5;
polyline.Path = new Geopath(coordinates);
nativeMap.MapElements.Add(polyline);
}
}
}
I also read that a key is needed, so maybe I doesn't use this key in a good way.. I tried with UWP Public Key and WinPhone8.X and earlier Key, but without success too..
Does someone has an idea? This part a really big problem in my app..
Thank in advance !
After a long time, I found why it didn't works...
If you're doing like me, if you do a HttpRequest to something as Google Direction API, then the result will comes after the first passage in the OnElementChanged().
Because formsMap.RouteCoordinates isn't null but empty, the Catastrophic failure (Exception from HRESULT: 0x8000FFFF (E_UNEXPECTED)) is thrown..
This is the good CustomMapRenderer for PolyLine use
using PROJECT;
using PROJECT.UWP;
using System.Collections.Generic;
using Windows.Devices.Geolocation;
using Windows.UI.Xaml.Controls.Maps;
using Xamarin.Forms.Maps;
using Xamarin.Forms.Maps.UWP;
using Xamarin.Forms.Platform.UWP;
[assembly: ExportRenderer(typeof(CustomMap), typeof(CustomMapRenderer))]
namespace PROJECT.UWP
{
public class CustomMapRenderer : MapRenderer
{
MapControl nativeMap;
CustomMap formsMap;
protected override void OnElementChanged(ElementChangedEventArgs<Map> e)
{
base.OnElementChanged(e);
if (e.OldElement != null)
{
nativeMap = Control as MapControl;
}
if (e.NewElement != null)
{
formsMap = (CustomMap)e.NewElement;
nativeMap = Control as MapControl;
UpdatePolyLine();
}
}
protected override void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (this.Element == null || this.Control == null)
return;
if (e.PropertyName == CustomMap.RouteCoordinatesProperty.PropertyName)
{
UpdatePolyLine();
}
}
private void UpdatePolyLine()
{
if (formsMap != null && formsMap.RouteCoordinates.Count > 0)
{
List<BasicGeoposition> coordinates = new List<BasicGeoposition>();
foreach (var position in formsMap.RouteCoordinates)
{
coordinates.Add(new BasicGeoposition() { Latitude = position.Latitude, Longitude = position.Longitude });
}
Geopath path = new Geopath(coordinates);
MapPolyline polyline = new MapPolyline();
polyline.StrokeColor = Windows.UI.Color.FromArgb(128, 255, 0, 0);
polyline.StrokeThickness = 5;
polyline.Path = path;
nativeMap.MapElements.Add(polyline);
}
}
}
}

GoogleMaps displaying "locals" on wrong position

i want to display the CurrentPosition of the mobile phone and display all bar|cafe nearby the position.
The CurrentPosition works.
But the displaying of the bars/cafes is wrong. It seems like they are showing up from the center of vienna and not from the position of my phone.
Would be really thankful if someone could find the problem
MapsActivity.java
package androfenix.currentpositionandplacesnearby;
import android.Manifest;
import android.content.pm.PackageManager;
import android.location.Location;
import android.os.AsyncTask;
import android.os.Build;
import android.support.v4.app.ActivityCompat;
import android.os.Bundle;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.Toast;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class MapsActivity extends AppCompatActivity implements OnMapReadyCallback,
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,
LocationListener {
private GoogleMap mMap;
GoogleApiClient mGoogleApiClient;
Location mLastLocation;
Marker mCurrLocationMarker;
LocationRequest mLocationRequest;
LatLng latLng;
double mLatitude=0;
double mLongitude=0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
checkLocationPermission();
}
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
//Mit setMapType setzen wir das Aussehen der Karte auf "Hybrid"
mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
//Initialize Google Play Services
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
buildGoogleApiClient();
mMap.setMyLocationEnabled(true);
}
}
else {
buildGoogleApiClient();
mMap.setMyLocationEnabled(true);
}
}
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
mGoogleApiClient.connect();
}
#Override
public void onPause()
{
super.onPause();
//Unregister for location callbacks:
if (mGoogleApiClient != null)
{
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
}
}
#Override
public void onConnected(Bundle bundle) {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(1000);
mLocationRequest.setFastestInterval(1000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onLocationChanged(Location location) {
mLastLocation = location;
if (mCurrLocationMarker != null) {
mCurrLocationMarker.remove();
}
// Create a LatLng object for the current location
latLng = new LatLng(location.getLatitude(), location.getLongitude());
mLatitude = location.getLatitude();
mLongitude = location.getLongitude();
//Place current location marker
LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(latLng);
markerOptions.title("Current Position");
markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA));
mCurrLocationMarker = mMap.addMarker(markerOptions);
//move map camera
mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
mMap.animateCamera(CameraUpdateFactory.zoomTo(11));
//stop location updates
if (mGoogleApiClient != null) {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
}
StringBuilder sbValue = new StringBuilder(sbMethod());
PlacesTask placesTask = new PlacesTask();
placesTask.execute(sbValue.toString());
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
}
public static final int MY_PERMISSIONS_REQUEST_LOCATION = 99;
public boolean checkLocationPermission(){
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
// Asking user if explanation is needed
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.ACCESS_FINE_LOCATION)) {
// Show an explanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
//Prompt the user once explanation has been shown
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_LOCATION);
} else {
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_LOCATION);
}
return false;
} else {
return true;
}
}
#Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_LOCATION: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted. Do the
// contacts-related task you need to do.
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
if (mGoogleApiClient == null) {
buildGoogleApiClient();
}
mMap.setMyLocationEnabled(true);
}
} else {
// Permission denied, Disable the functionality that depends on this permission.
Toast.makeText(this, "permission denied", Toast.LENGTH_LONG).show();
}
return;
}
// other 'case' lines to check for other permissions this app might request.
// You can add here other case statements according to your requirement.
}
}
public StringBuilder sbMethod() throws SecurityException
{
StringBuilder sb = new StringBuilder("https://maps.googleapis.com/maps/api/place/nearbysearch/json?");
sb.append("location=" + mLatitude + "," + mLongitude);
sb.append("&radius=50000");
sb.append("&sensor=true");
sb.append("&keyword=" + "bar|cafe");
sb.append("&key= SERVER API KEY ");
Log.d("Map", "url: " + sb.toString());
return sb;
}
private class PlacesTask extends AsyncTask<String, Integer, String>
{
String data = null;
// Invoked by execute() method of this object
#Override
protected String doInBackground(String... url) {
try {
data = downloadUrl(url[0]);
} catch (Exception e) {
Log.d("Background Task", e.toString());
}
return data;
}
// Executed after the complete execution of doInBackground() method
#Override
protected void onPostExecute(String result) {
ParserTask parserTask = new ParserTask();
// Start parsing the Google places in JSON format
// Invokes the "doInBackground()" method of the class ParserTask
parserTask.execute(result);
}
}
private String downloadUrl(String strUrl) throws IOException
{
String data = "";
InputStream iStream = null;
HttpURLConnection urlConnection = null;
try {
URL url = new URL(strUrl);
// Creating an http connection to communicate with url
urlConnection = (HttpURLConnection) url.openConnection();
// Connecting to url
urlConnection.connect();
// Reading data from url
iStream = urlConnection.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(iStream));
StringBuffer sb = new StringBuffer();
String line = "";
while ((line = br.readLine()) != null) {
sb.append(line);
}
data = sb.toString();
br.close();
} catch (Exception e) {
Log.d("Exception", e.toString());
} finally {
iStream.close();
urlConnection.disconnect();
}
return data;
}
private class ParserTask extends AsyncTask<String, Integer, List<HashMap<String, String>>> {
JSONObject jObject;
// Invoked by execute() method of this object
#Override
protected List<HashMap<String, String>> doInBackground(String... jsonData) {
List<HashMap<String, String>> places = null;
Place_JSON placeJson = new Place_JSON();
try {
jObject = new JSONObject(jsonData[0]);
places = placeJson.parse(jObject);
} catch (Exception e) {
Log.d("Exception", e.toString());
}
return places;
}
// Executed after the complete execution of doInBackground() method
#Override
protected void onPostExecute(List<HashMap<String, String>> list) {
Log.d("Map", "list size: " + list.size());
// Clears all the existing markers;
//mGoogleMap.clear();
for (int i = 0; i < list.size(); i++) {
// Creating a marker
MarkerOptions markerOptions = new MarkerOptions();
// Getting a place from the places list
HashMap<String, String> hmPlace = list.get(i);
// Getting latitude of the place
double lat = Double.parseDouble(hmPlace.get("lat"));
// Getting longitude of the place
double lng = Double.parseDouble(hmPlace.get("lng"));
// Getting name
String name = hmPlace.get("place_name");
Log.d("Map", "place: " + name);
// Getting vicinity
String vicinity = hmPlace.get("vicinity");
latLng = new LatLng(lat, lng);
// Setting the position for the marker
markerOptions.position(latLng);
markerOptions.title(name + " : " + vicinity);
markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA));
// Placing a marker on the touched position
Marker m = mMap.addMarker(markerOptions);
// ZZZZZZZZZZZZZZZZZZZ
}
}
}
public class Place_JSON {
/**
* Receives a JSONObject and returns a list
*/
public List<HashMap<String, String>> parse(JSONObject jObject) {
JSONArray jPlaces = null;
try {
/** Retrieves all the elements in the 'places' array */
jPlaces = jObject.getJSONArray("results");
} catch (JSONException e) {
e.printStackTrace();
}
/** Invoking getPlaces with the array of json object
* where each json object represent a place
*/
return getPlaces(jPlaces);
}
private List<HashMap<String, String>> getPlaces(JSONArray jPlaces) {
int placesCount = jPlaces.length();
List<HashMap<String, String>> placesList = new ArrayList<HashMap<String, String>>();
HashMap<String, String> place = null;
/** Taking each place, parses and adds to list object */
for (int i = 0; i < placesCount; i++) {
try {
/** Call getPlace with place JSON object to parse the place */
place = getPlace((JSONObject) jPlaces.get(i));
placesList.add(place);
} catch (JSONException e) {
e.printStackTrace();
}
}
return placesList;
}
/**
* Parsing the Place JSON object
*/
private HashMap<String, String> getPlace(JSONObject jPlace)
{
HashMap<String, String> place = new HashMap<String, String>();
String placeName = "-NA-";
String vicinity = "-NA-";
String latitude = "";
String longitude = "";
String reference = "";
try {
// Extracting Place name, if available
if (!jPlace.isNull("name")) {
placeName = jPlace.getString("name");
}
// Extracting Place Vicinity, if available
if (!jPlace.isNull("vicinity")) {
vicinity = jPlace.getString("vicinity");
}
latitude = jPlace.getJSONObject("geometry").getJSONObject("location").getString("lat");
longitude = jPlace.getJSONObject("geometry").getJSONObject("location").getString("lng");
reference = jPlace.getString("reference");
place.put("place_name", placeName);
place.put("vicinity", vicinity);
place.put("lat", latitude);
place.put("lng", longitude);
place.put("reference", reference);
} catch (JSONException e) {
e.printStackTrace();
}
return place;
}
}
}
Using the Google Places API for Android, you can discover the place where the device is currently located. That is, the place at the device's currently-reported location. Examples of places include local businesses, points of interest, and geographic locations.
If your app uses PlaceDetectionApi.getCurrentPlace() must request the ACCESS_FINE_LOCATION permission.
The following code sample retrieves the list of places where the device is most likely to be located, and logs the name and likelihood for each place.
PendingResult<PlaceLikelihoodBuffer> result = Places.PlaceDetectionApi
.getCurrentPlace(mGoogleApiClient, null);
result.setResultCallback(new ResultCallback<PlaceLikelihoodBuffer>() {
#Override
public void onResult(PlaceLikelihoodBuffer likelyPlaces) {
for (PlaceLikelihood placeLikelihood : likelyPlaces) {
Log.i(TAG, String.format("Place '%s' has likelihood: %g",
placeLikelihood.getPlace().getName(),
placeLikelihood.getLikelihood()));
}
likelyPlaces.release();
}
});
The PlacePicker provides a UI dialog that displays an interactive map and a list of nearby places, including places corresponding to geographical addresses and local businesses. Users can choose a place, and your app can then retrieve the details of the selected place.
The following code snippet retrieves the place that the user has selected:
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == PLACE_PICKER_REQUEST) {
if (resultCode == RESULT_OK) {
Place place = PlacePicker.getPlace(data, this);
String toastMsg = String.format("Place: %s", place.getName());
Toast.makeText(this, toastMsg, Toast.LENGTH_LONG).show();
}
}
}

Android Fragment : replace Crash and Hide/show don't works

I'm making an App that implements this slide-out Menu and i'm pretty much satisfied about the implementation.
I divided my app in multiple Fragment for one Activity so for each section of the menu there is a Fragment.
The point is that i have an OnItemClickListener that allow me to switch beetween Fragments, so I'd tried two methods :
replace() : it works fine for all fragment except for one of them that load a XML which contains a map (code below). On first load there's no problem but when I switch to another fragment and came back to the one with the map, the app crash.
<fragment
android:id="#+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.google.android.gms.maps.SupportMapFragment" />
<RelativeLayout
android:id="#+id/RelativeLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ImageButton
android:id="#+id/refreshButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_marginTop="63dp"
android:src="#drawable/refresh"
android:text="Rafraichir" />
</RelativeLayout>
public class MapFragment extends Fragment implements
OnInfoWindowClickListener, LocationListener {
private GoogleMap gMap;
Geocoder geocoder;
private LocationManager locationManager;
private Location userLocation;
private String provider;
private ImageButton refreshButton;
ArrayList<Parking> Parkings;
Context context;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.fragmen_map,
container, false);
gMap = ((SupportMapFragment) getFragmentManager().findFragmentById(
R.id.map)).getMap();
gMap.setOnInfoWindowClickListener(this);
context = getActivity();
geocoder = new Geocoder(context);
refreshButton = (ImageButton) view.findViewById(R.id.refreshButton);
refreshButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
getParkingsConnection = new GetParkingsConnection(context);
getParkingsConnection.execute(null, null, null);
myParkings = new ArrayList<Parking>();
}
});
// Geolocaliation
LocationManager service = (LocationManager) getActivity()
.getSystemService(getActivity().LOCATION_SERVICE);
boolean enabled = service
.isProviderEnabled(LocationManager.GPS_PROVIDER);
// Check if enabled and if not send user to the GSP settings
// Better solution would be to display a dialog and suggesting to
// go to the settings
if (!enabled) {
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(intent);
}
// Get the location manager
locationManager = (LocationManager) getActivity().getSystemService(
getActivity().LOCATION_SERVICE);
// Define the criteria how to select the locatioin provider -> use
// default
Criteria criteria = new Criteria();
provider = locationManager.getBestProvider(criteria, false);
Location location = locationManager.getLastKnownLocation(provider);
return view;
}
private Double[] getLatAndLong(String addresse) {
List<Address> addresses = null;
Double latALng[] = new Double[2];
try {
addresses = geocoder.getFromLocationName(addresse, 1);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (addresses.size() > 0) {
double latitude = addresses.get(0).getLatitude();
double longitude = addresses.get(0).getLongitude();
latALng[0] = latitude;
latALng[1] = longitude;
}
return latALng;
}
private GetParkingsConnection getParkingsConnection;
JSONObject json;
// Non-Statice inner class : connection au serveur
private class GetParkingsConnection extends AsyncTask<String, Void, String> {
Context mContext;
private ProgressDialog mDialog;
GetParkingsConnection(Context context) {
mContext = context;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
mDialog = new ProgressDialog(mContext);
mDialog.setMessage("Mise à jour de la carte...");
mDialog.show();
}
#Override
protected String doInBackground(String... urls) {
String resultat;
resultat = getParkings();
return resultat;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
Log.d("JSON", result);
JSONArray jArray;
try {
json = new JSONObject(result);
jArray = json.getJSONArray("parking");
System.out.println("*****Parkings*****" + jArray.length());
for (int i = 0; i < jArray.length(); i++) {
JSONObject json_data = jArray.getJSONObject(i);
Log.d("adresse :",
json_data.getString("adresse") + ", nom :"
+ json_data.getString("nom")
+ ", latitude :"
+ json_data.getDouble("latitude")
+ ", longitude :"
+ json_data.getDouble("longitude"));
String adresse = json_data.getString("adresse");
Double latALng[] = getLatAndLong(adresse);
Double lat = latALng[0]; // json_data.getDouble("latitude");
Double lng = latALng[1]; // json_data.getDouble("longitude");
String nom = json_data.getString("nom");
LatLng parkingLocation = new LatLng(lat, lng);
Marker parking = gMap.addMarker(new MarkerOptions()
.position(parkingLocation)
.title(nom)
.snippet(adresse)
.icon(BitmapDescriptorFactory
.fromResource(R.drawable.my_marker)));
Parking park = new Parking(parking.getId(), adresse, nom,
"", lat, lng);
myParkings.add(park);
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mDialog.dismiss();
}
// Fonction effectuant uenrequête de type GET sur le fichier
// getParking.php
protected String getParkings() {
HttpResponse response = null;
String res = "";
try {
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet();
// request.setURI(new
// URI("http://pkdom.1x.biz/getParkings.php"));
request.setURI(new URI(
"http://glennsonna.fr/webService/getParkings"));
response = client.execute(request);
HttpEntity entity = response.getEntity();
// JSONObject json = new JSONObject();
res = EntityUtils.toString(entity);
} catch (URISyntaxException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return res;
}
}
#Override
public void onInfoWindowClick(Marker marker) {
// TODO Auto-generated method stub
Parking parkingToSend = null;
// TOAST
/*
* int p = 0;
*
* while(myParkings.get(p).idMarker != marker.getId() && p <
* myParkings.size()){ Log.d("Marker :" + marker.getId(),
* myParkings.get(p).idMarker);
*
* if(myParkings.get(p).idMarker.equals(marker.getId()) ){
* parkingToSend = myParkings.get(p); Context context =
* getApplicationContext(); CharSequence text = "Match" +
* parkingToSend.adresse; int duration = Toast.LENGTH_SHORT; Toast toast
* = Toast.makeText(context, text, duration); toast.show(); }
*
* p++; }
*/
for (int p = 0; p < myParkings.size(); p++) {
Log.d("Marker :" + marker.getId(), myParkings.get(p).idMarker);
if (myParkings.get(p).idMarker.equals(marker.getId())) {
parkingToSend = myParkings.get(p);
}
}
if (parkingToSend != null) {
Intent i = new Intent(context.getApplicationContext(),
ParkingDetail.class);
i.putExtra("id", parkingToSend.idMarker);
i.putExtra("adresse", parkingToSend.adresse);
i.putExtra("nom", parkingToSend.nom);
i.putExtra("descri", parkingToSend.description);
i.putExtra("latitude", parkingToSend.lat);
i.putExtra("longitude", parkingToSend.lng);
startActivity(i);
}
}
#Override
public void onLocationChanged(Location user) {
// TODO Auto-generated method stub
Log.d("Latitude", ":" + user.getLatitude());
Log.d("Longitude", ":" + user.getLongitude());
this.gMap.setMyLocationEnabled(true);
}
#Override
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
}
hide() & show() : I can switch beetween fragment but excepted for the first screen (the map) all the other show a blank screen without content.
private MenuDrawer mMenuDrawer;
private MenuAdapter mAdapter;
private ListView mList;
private GoogleMap gMap;
private int mActivePosition = -1;
List<Object> mmyFragment;
Fragment currentFragment;
myMapFragment mmyMapFragment;
myMonCompteFragment mmyMonCompteFragment;
myPaiementFragment mmyPaiementFragment;
myReservationsFragment mmyReservationsFragment;
myFavorisFragment mmyFavorisFragment;
myCodePromoFragment mmyCodePromoFragment;
myAboutFragment mmyAboutFragment;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// setContentView(R.layout.activity_my_map);
ActionBar actionBar = this.getActionBar();
actionBar.setSubtitle("Trouvez votre parking");
actionBar.setTitle("my");
actionBar.setDisplayHomeAsUpEnabled(true);
setupMenu();
setupFragments();
}
private void setupMenu() {
mMenuDrawer = MenuDrawer.attach(this, Position.LEFT);
mMenuDrawer.setContentView(R.layout.activity_my_map);
List<Object> items = new ArrayList<Object>();
items.add(new Item("Carte", R.drawable.ic_action_refresh_dark));
items.add(new Item("Mon Compte", R.drawable.ic_action_refresh_dark));
items.add(new Item("Paiement", R.drawable.ic_action_select_all_dark));
items.add(new Item("Mes Réservations",
R.drawable.ic_action_select_all_dark));
items.add(new Item("Mes favoris", R.drawable.ic_action_refresh_dark));
// items.add(new Category(" "));
items.add(new Item("Code Promo", R.drawable.ic_action_refresh_dark));
items.add(new Item("A propos", R.drawable.ic_action_select_all_dark));
// A custom ListView is needed so the drawer can be notified when it's
// scrolled. This is to update the position
// of the arrow indicator.
mList = new ListView(this);
mAdapter = new MenuAdapter(items);
mList.setAdapter(mAdapter);
mList.setOnItemClickListener(mItemClickListener);
mMenuDrawer.setMenuView(mList);
}
private void setupFragments() {
mmyMapFragment = new myMapFragment();
mmyMonCompteFragment = new myMonCompteFragment();
mmyPaiementFragment = new myPaiementFragment();
mmyReservationsFragment = new myReservationsFragment();
mmyFavorisFragment = new myFavorisFragment();
mmyCodePromoFragment = new myCodePromoFragment();
mmyAboutFragment = new myAboutFragment();
mmyFragment = new ArrayList<Object>();
mmyFragment.add(mmyMapFragment);
mmyFragment.add(mmyMonCompteFragment);
mmyFragment.add(mmyPaiementFragment);
mmyFragment.add(mmyReservationsFragment);
mmyFragment.add(mmyFavorisFragment);
mmyFragment.add(mmyCodePromoFragment);
mmyFragment.add(mmyAboutFragment);
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager
.beginTransaction();
fragmentTransaction.replace(R.id.myContenu, mmyMapFragment);
fragmentTransaction.commit();
currentFragment = mmyMapFragment;
}
private AdapterView.OnItemClickListener mItemClickListener = new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
mActivePosition = position;
mMenuDrawer.setActiveView(view, position);
mMenuDrawer.closeMenu();
if ((mmyFragment.get(position) != null)
/*&& (mmyFragment.get(position).getClass() != currentFragment
.getClass())*/) {
Fragment nexFragment = (Fragment) mmyFragment
.get(position);
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager
.beginTransaction();
fragmentTransaction.setCustomAnimations(android.R.anim.fade_in,
android.R.anim.fade_out);
fragmentTransaction.hide(currentFragment);
if (!nexFragment.isHidden()) {
//fragmentTransaction.add(nexFragment, nexFragment.getTag());
Toast.makeText(
getApplicationContext(),
""
+ nexFragment.getClass().toString()
+ " : "
+ mmyFragment.indexOf(mmyFragment
.get(position)), Toast.LENGTH_SHORT).show();
}
//fragmentTransaction.addToBackStack(nexFragment.getTag());
fragmentTransaction.attach(nexFragment);
fragmentTransaction.replace(R.id.myContenu, nexFragment);
//fragmentTransaction.show(nexFragment);
currentFragment = nexFragment;
fragmentTransaction.commit();...}
After one day i finaly found the answer here
So i just implemented the code below. But I have to use replace(); so I'll find a way to save my map state.
public void onDestroyView ()
{
try{
SupportMapFragment fragment = ((SupportMapFragment) getFragmentManager().findFragmentById(R.id.map));
FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
ft.remove(fragment);
ft.commit();
}catch(Exception e){
}
super.onDestroyView();
}

Google Maps Compass crashes with onPause & onCreate (removing them works but I don't have compass)

If I comment the onPause compass.disable and onResume compass.Enable apps start and work but I don't have the compass on my Google map.
On the other hand if I uncomment these two line the apps don't even show. Like is blocked, then I again comment this two line and emulator again work. So somewhere is problem with compass but I don't see where, any help.
MapView map;
MyLocationOverlay compass;
MapController controller;
GeoPoint touchedPoint;
Drawable d;
List<Overlay> overlayList;
LocationManager lm;
String towers;
long start;
long stop;
int x, y;
int latit;
int longi;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_LEFT_ICON);// dodao za favicon
setContentView(R.layout.activity_main);
setFeatureDrawableResource(Window.FEATURE_LEFT_ICON, R.drawable.logo);
map = (MapView) findViewById(R.id.mvMain);
map.setBuiltInZoomControls(true);
this.setTitle("EasyMaps=QRZ");
Touchy t = new Touchy();
overlayList = map.getOverlays();
overlayList.add(t);
compass = new MyLocationOverlay(MainActivity.this, map);
overlayList.add(compass);
controller = map.getController();
GeoPoint point = new GeoPoint((int) (47.975 * 1E6), (int) (17.056 * 1E6));
controller.animateTo(point);
controller.setZoom(17);
d = getResources().getDrawable(R.drawable.icon);
lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Criteria crit = new Criteria();
towers = lm.getBestProvider(crit, false);
Location location = lm.getLastKnownLocation(towers);
if (location != null) {
latit = (int) (location.getLatitude() * 1E6);
longi = (int) (location.getLongitude() * 1E6);
GeoPoint ourLocation = new GeoPoint(latit, longi);
OverlayItem overlayitem = new OverlayItem(ourLocation, "Location", "Location");
CustomPinpoint custom = new CustomPinpoint(d, MainActivity.this);
custom.insertPinpoint(overlayitem);
overlayList.add(custom);
} else {
Toast.makeText(MainActivity.this, "Provider not avaiable!", Toast.LENGTH_SHORT).show();
}
}
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Checks the orientation of the screen
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show();
} else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show();
}
}
#Override
protected void onResume() {
super.onResume();
compass.enableCompass();//Problem
lm.requestLocationUpdates(towers, 500, 1, this);
}
#Override
protected void onPause() {
super.onPause();
compass.disableCompass();//Problem
lm.removeUpdates(this);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
#Override
protected boolean isRouteDisplayed() {
// TODO Auto-generated method stub
return false;
}
class Touchy extends Overlay {
public boolean onTouchEvent(MotionEvent e, MapView m) {
if (e.getAction() == MotionEvent.ACTION_DOWN) {
start = e.getEventTime();
x = (int) e.getX() + 11;
y = (int) e.getY() - 15;
touchedPoint = map.getProjection().fromPixels(x, y);
}
if (e.getAction() == MotionEvent.ACTION_UP) {
stop = e.getEventTime();
}
if (stop - start > 1500) {
// to do action
AlertDialog alert = new AlertDialog.Builder(MainActivity.this).create();
alert.setTitle("Option panel");
alert.setMessage("Choose an option!");
alert.setButton("Put flag", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
OverlayItem overlayitem = new OverlayItem(touchedPoint, "Flag", "Flag");
CustomPinpoint custom = new CustomPinpoint(d, MainActivity.this);
custom.insertPinpoint(overlayitem);
overlayList.add(custom);
}
});
alert.setButton2("Get address", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
Geocoder geocoder = new Geocoder(getBaseContext(), Locale.getDefault());
try {
List<Address> address = geocoder.getFromLocation(touchedPoint.getLatitudeE6() / 1E6, touchedPoint.getLongitudeE6() / 1E6, 1);
if (address.size() > 0) {
String display = "";
for (int i = 0; i < address.get(0).getMaxAddressLineIndex(); i++) {
display += address.get(0).getAddressLine(i) + "\n";
}
Toast t3 = Toast.makeText(getBaseContext(), display, Toast.LENGTH_LONG);
t3.show();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
// Nista
}
}
});
alert.setButton3("View", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
if (map.isSatellite()) {
map.setSatellite(false);
map.setStreetView(true);
} else {
map.setStreetView(false);
map.setSatellite(true);
}
}
});
alert.show();
return true;
}
return false;
}
}
#Override
public void onLocationChanged(Location l) {
// TODO Auto-generated method stub
latit = (int) (l.getLatitude() * 1E6);
longi = (int) (l.getLongitude() * 1E6);
GeoPoint ourLocation = new GeoPoint(latit, longi);
OverlayItem overlayitem = new OverlayItem(ourLocation, "Location", "LOcation");
CustomPinpoint custom = new CustomPinpoint(d, MainActivity.this);
custom.insertPinpoint(overlayitem);
overlayList.add(custom);
}
#Override
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
}
You may want to use different names. What you call "compass" is actually your location, and it will certainly behave differently from a compass - it will mostly point in a different direction, for starters.
Before you try to enable or disable the MyLocation overlay, you need to check if it is actually non-null.
if (mMyLocationOverlay != null)
mMyLocationOverlay.disableMyLocation();