首页 > 解决方案 > 在 com.projects.fragments.MapFragment.refetch(MapFragment.java:207)

问题描述

我在以下位置出现错误:

com.projects.fragments.MapFragment.onMapReady(MapFragment.java:200) 在 com.projects.fragments.MapFragment.onMapReady(MapFragment.java:200) 在 com.google.android.gms.maps.SupportMapFragment$zza$1.zza (未知来源)在 com.google.android.gms.maps.internal.zzo$zza.onTransact(未知来源)

发生在运行时这个Mapfragment

 package com.projects.fragments;

 import android.annotation.SuppressLint;
 import android.content.ComponentName;
 import android.content.Intent;
 import android.graphics.Bitmap;
 import android.location.Location;
 import android.net.Uri;
 import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
 import android.provider.Settings;
 import android.support.v4.app.Fragment;
 import android.support.v4.app.FragmentManager;
import android.support.v4.widget.SwipeRefreshLayout;
 import android.support.v7.app.AppCompatActivity;
import android.text.Html;
  import android.text.Spanned;
import android.util.Log;
   import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
  import android.view.animation.Animation;
 import android.view.animation.AnimationUtils;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ToggleButton;

import com.application.RealEstateApplication;
import com.config.Config;
import com.config.UIConfig;
import com.db.Queries;
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.CameraPosition;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.LatLngBounds;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.maps.model.PolygonOptions;
import com.google.android.gms.maps.model.PolylineOptions;
import com.libraries.asynctask.MGAsyncTask;
import com.libraries.asynctask.MGAsyncTaskNoDialog;
import com.libraries.dataparser.DataParser;
import com.libraries.drawingview.DrawingView;
import com.libraries.location.MGLocationManagerUtils;
import com.libraries.sliding.MGSliding;
import com.libraries.usersession.UserAccessSession;
import com.libraries.utilities.MGUtilities;
import com.models.DataResponse;
import com.models.Favorite;
import com.models.Photo;
import com.models.PropertyType;
import com.models.RealEstate;
 import com.projects.activities.DetailActivity;
 import com.projects.realestatefinder.R;

  import java.lang.reflect.Array;
  import java.util.ArrayList;
  import java.util.Collections;
  import java.util.Comparator;
  import java.util.HashMap;

 import butterknife.ButterKnife;
 import butterknife.OnClick;
  import butterknife.Unbinder;

/**
 * Created by mg on 27/07/16.
*/

  public class MapFragment extends Fragment implements OnMapReadyCallback,
    RealEstateApplication.OnLocationListener,

    GoogleMap.OnInfoWindowClickListener, GoogleMap.OnMapClickListener,  
 DrawingView.OnDrawingViewListener {

private View viewInflate;
private GoogleMap googleMap;
private MGSliding frameSliding;
SwipeRefreshLayout swipeRefresh;
MGAsyncTaskNoDialog task;
ArrayList<RealEstate> realEstates;
private HashMap<String, RealEstate> markers;
private ArrayList<Marker> markerList;
private RealEstate selectedRealEstate;
private DrawingView drawingView;
private Unbinder unbinder;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    viewInflate = inflater.inflate(R.layout.fragment_map, null);
    unbinder = ButterKnife.bind(this, viewInflate);
    return viewInflate;
}

@Override
public void onDestroyView() {
    super.onDestroyView();
    unbinder.unbind();

    if(task != null)
        task.cancel(true);
}

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

@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onViewCreated(view, savedInstanceState);

    realEstates = new ArrayList<RealEstate>();
    swipeRefresh = (SwipeRefreshLayout) viewInflate.findViewById(R.id.swipe_refresh);
    swipeRefresh.setClickable(false);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
        swipeRefresh.setProgressViewOffset(false, 0,100);
    }

    swipeRefresh.setColorSchemeResources(
            android.R.color.holo_blue_bright,
            android.R.color.holo_green_light,
            android.R.color.holo_orange_light,
            android.R.color.holo_red_light);

    showRefresh(false);

    FragmentManager fManager = getActivity().getSupportFragmentManager();
    SupportMapFragment supportMapFragment = ((SupportMapFragment) fManager.findFragmentById(R.id.googleMap));
    if(supportMapFragment == null) {
        fManager = getChildFragmentManager();
        supportMapFragment = ((SupportMapFragment) fManager.findFragmentById(R.id.googleMap));
    }
    supportMapFragment.getMapAsync(this);

    frameSliding = (MGSliding) viewInflate.findViewById(R.id.frameSliding);
    Animation animationIn = AnimationUtils.loadAnimation(this.getActivity(), R.anim.slide_up2);
    Animation animationOut = AnimationUtils.loadAnimation(this.getActivity(), R.anim.slide_down2);

    frameSliding.setInAnimation(animationIn);
    frameSliding.setOutAnimation(animationOut);
    frameSliding.setVisibility(View.GONE);

    markers = new HashMap<String, RealEstate>();
    markerList = new ArrayList<Marker>();
}

@Override
public void onMapReady(GoogleMap _googleMap) {
    googleMap = _googleMap;
    googleMap.setOnInfoWindowClickListener(this);
    googleMap.setOnCameraChangeListener(new GoogleMap.OnCameraChangeListener() {
        @Override
        public void onCameraChange(CameraPosition cameraPosition) {
            if(frameSliding.getVisibility() == View.VISIBLE)
                frameSliding.setVisibility(View.INVISIBLE);
        }
    });

    drawingView = (DrawingView) viewInflate.findViewById(R.id.drawingView);
    drawingView.setBrushSize(5);
    drawingView.setPolygonFillColor(getResources().getColor(R.color.colorPrimaryAlpha));
    drawingView.setColor(getResources().getColor(R.color.colorAccent));
    drawingView.setPolylineColor(getResources().getColor(R.color.colorAccent));
    drawingView.setGoogleMap(googleMap);
    drawingView.setOnDrawingViewListener(this);

    if(!MGUtilities.isLocationEnabled(getActivity()) && RealEstateApplication.currentLocation == null) {
        MGLocationManagerUtils utils = new MGLocationManagerUtils();
        utils.setOnAlertListener(new MGLocationManagerUtils.OnAlertListener() {
            @Override
            public void onPositiveTapped() {
                startActivityForResult(
                        new Intent(
                                Settings.ACTION_LOCATION_SOURCE_SETTINGS),
                        Config.PERMISSION_REQUEST_LOCATION_SETTINGS);
            }

            @Override
            public void onNegativeTapped() {
                showRefresh(false);
            }
        });
        utils.showAlertView(
                getActivity(),
                R.string.location_error,
                R.string.gps_not_on,
                R.string.go_to_settings,
                R.string.cancel);
    }
    else {
        showRefresh(true);
        if(RealEstateApplication.currentLocation != null) {
            getData();
        }
        else {
            refetch();
        }
    }
}

public void refetch() {
    showRefresh(true);
    RealEstateApplication app = (RealEstateApplication) getActivity().getApplication();
    app.setOnLocationListener(this, getActivity());
}

private void getData() {
    showRefresh(true);
    task = new MGAsyncTaskNoDialog(getActivity());
    task.setMGAsyncTaskListener(new MGAsyncTaskNoDialog.OnMGAsyncTaskListenerNoDialog() {

        @Override
        public void onAsyncTaskProgressUpdate(MGAsyncTaskNoDialog asyncTask) { }

        @Override
        public void onAsyncTaskPreExecute(MGAsyncTaskNoDialog asyncTask) {
        }

        @Override
        public void onAsyncTaskPostExecute(MGAsyncTaskNoDialog asyncTask) {
            // TODO Auto-generated method stub
            showRefresh(false);
            addMarkers(realEstates);
    //    showBoundedMap();
        }

        @Override
        public void onAsyncTaskDoInBackground(MGAsyncTaskNoDialog asyncTask) {
            // TODO Auto-generated method stub
            if(RealEstateApplication.currentLocation != null && MGUtilities.hasConnection(getContext())) {
                try {
                    UserAccessSession accessSession = UserAccessSession.getInstance(getActivity());
                    float radius = accessSession.getFilterDistance();
                    if(radius == 0)
                        radius = Config.DEFAULT_FILTER_DISTANCE_IN_KM;

                    String strUrl = String.format("%s?api_key=%s&lat=%f&lon=%f&radius=%f&get_propertytypes=1&default_count_to_find_distance=%d",
                            Config.GET_DATA_JSON_URL,
                            Config.API_KEY,
                            RealEstateApplication.currentLocation.getLatitude(),
                            RealEstateApplication.currentLocation.getLongitude(),
                            radius,
                            Config.DEFAULT_COUNT_TO_FIND);

                    Log.e("URL", strUrl);
                    DataParser parser = new DataParser();
                    DataResponse data = parser.getData(strUrl);
                    if (data == null)
                        return;

                    if(data.getMax_distance() > 0) {
                        UserAccessSession.getInstance(getActivity()).setFilterDistanceMax(data.getMax_distance());
                    }

                    if(Config.AUTO_ADJUST_DISTANCE) {
                        if(UserAccessSession.getInstance(getActivity()).getFilterDistance() == 0) {
                            UserAccessSession.getInstance(getActivity()).setFilterDistance(data.getDefault_distance());
                        }
                    }

                    Queries q = RealEstateApplication.getQueriesInstance(getContext());
                    if (data.getProperty_types() != null && data.getProperty_types().size() > 0) {
                        for (PropertyType obj : data.getProperty_types()) {
                            q.deletePropertyType(obj.getPropertytype_id());
                            q.insertPropertyType(obj);
                        }
                    }

                    if (data.getReal_estates() != null && data.getReal_estates().size() > 0) {
                        for (RealEstate obj : data.getReal_estates()) {
                            double distance = obj.getDistance() * Config.CONVERSION_SERVER_DATA_DISTANCE_TO_KM;
                            obj.setDistance(distance);

                            q.deleteRealEstate(obj.getRealestate_id());
                            q.insertRealEstate(obj);
                            if (obj.getPhotos() != null && obj.getPhotos().size() > 0) {
                                for (Photo photo : obj.getPhotos()) {
                                    q.deletePhoto(photo.getPhoto_id());
                                    q.insertPhoto(photo);
                                }
                            }
                            if(obj.getAgent() != null) {
                                q.deleteAgent(obj.getAgent().getAgent_id());
                                q.insertAgent(obj.getAgent());
                            }
                            realEstates.add(obj);
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            else {
                realEstates = RealEstateApplication.getQueriesInstance(getContext()).getRealEstates();
                if(RealEstateApplication.currentLocation != null) {
                    for(RealEstate realEstate : realEstates) {
                        Location locStore = new Location("Store");
                        locStore.setLatitude(realEstate.getLat());
                        locStore.setLongitude(realEstate.getLon());
                        double userDistanceFromStore =
                                RealEstateApplication.currentLocation.distanceTo(locStore) *
                                        Config.CONVERSION_OFFLINE_DATA_DISTANCE_TO_KM;

                        realEstate.setDistance(userDistanceFromStore);
                    }

                    Collections.sort(realEstates, new Comparator<RealEstate>() {
                        @Override
                        public int compare(RealEstate obj1, RealEstate obj2) {
                            if (obj1.getDistance() < obj2.getDistance())
                                return -1;

                            if (obj1.getDistance() > obj2.getDistance())
                                return 1;

                            return 0;
                        }
                    });
                }
            }
        }
    });
    task.execute();
}


private void addMarkers(ArrayList<RealEstate> arrayList) {
    if(googleMap != null)
        googleMap.clear();

    try {
        markerList.clear();
        markers.clear();
        for(RealEstate entry: arrayList) {
            if(entry.getLat() == 0 || entry.getLon() == 0)
                continue;

            Marker mark = createMarker(entry);
            markerList.add(mark);
            markers.put(mark.getId(), entry);
        }
        showBoundedMap();
    }
    catch(Exception e) {
        e.printStackTrace();
    }
}

private Marker createMarker(RealEstate realEstate) {
    final MarkerOptions markerOptions = new MarkerOptions();
    String strPrice = String.format("%s %s", realEstate.getCurrency(), realEstate.getPrice());
    Spanned price = Html.fromHtml(strPrice);
    price = Html.fromHtml(price.toString());

    Spanned storeAddress = Html.fromHtml(realEstate.getAddress());
    storeAddress = Html.fromHtml(storeAddress.toString());
    markerOptions.title( price.toString() );

    String address = storeAddress.toString();
    if(address.length() > Config.ELLIPSE_HOME_COUNT)
        address = storeAddress.toString().substring(0, Config.ELLIPSE_HOME_COUNT) + "...";

    markerOptions.snippet(address);
    markerOptions.position(new LatLng(realEstate.getLat(), realEstate.getLon()));
    markerOptions.icon(BitmapDescriptorFactory.fromResource(UIConfig.MAP_PIN_REAL_ESTATE));

    Marker mark = googleMap.addMarker(markerOptions);
    mark.setInfoWindowAnchor(Config.MAP_INFO_WINDOW_X_OFFSET, 0);
    return mark;
}

private void showBoundedMap() {
    if(markerList == null && markerList.size() == 0 ) {
        Toast.makeText(getContext(), R.string.no_results_found, Toast.LENGTH_SHORT).show();
        return;
    }

    if(markerList.size() > 0) {
        LatLngBounds.Builder bld = new LatLngBounds.Builder();
        for (int i = 0; i < markerList.size(); i++) {
            Marker marker = markerList.get(i);
            bld.include(marker.getPosition());
        }

        LatLngBounds bounds = bld.build();
        googleMap.moveCamera(
                CameraUpdateFactory.newLatLngBounds(bounds,
                        this.getResources().getDisplayMetrics().widthPixels,
                        this.getResources().getDisplayMetrics().heightPixels,
                        70));
    }
    else {
        Toast.makeText(getContext(), R.string.no_results_found, Toast.LENGTH_SHORT).show();
        Location loc = RealEstateApplication.currentLocation;
        if(loc != null) {
            googleMap.moveCamera(
                    CameraUpdateFactory.newLatLngZoom(
                            new LatLng(loc.getLatitude(), loc.getLongitude()),
                            70) );
        }
    }
}

@Override
public void onInfoWindowClick(Marker marker) {
    // TODO Auto-generated method stub
    final RealEstate obj = markers.get(marker.getId());
    selectedRealEstate = obj;
    if(RealEstateApplication.currentLocation != null) {
        Location loc = new Location("marker");
        loc.setLatitude(marker.getPosition().latitude);
        loc.setLongitude(marker.getPosition().longitude);

        double meters = RealEstateApplication.currentLocation.distanceTo(loc);
        double miles = meters * Config.METERS_TO_KM;
        String str = String.format("%.1f %s",
                miles,
                MGUtilities.getStringFromResource(getActivity(), R.string.km));

        TextView tvDistance = (TextView) viewInflate.findViewById(R.id.tvDistance);
        tvDistance.setText(str);
    }

    frameSliding.setVisibility(View.VISIBLE);

    Queries q = RealEstateApplication.getQueriesInstance(getContext());
    ImageView imgViewThumb = (ImageView) viewInflate.findViewById(R.id.imgViewThumb);
    Photo p = q.getPhotoByRealEstateId(obj.getRealestate_id());
    if(p != null) {
        RealEstateApplication.getImageLoaderInstance(
                getActivity()).displayImage(p.getPhoto_url(),
                imgViewThumb,
                RealEstateApplication.getDisplayImageOptionsInstance());
    }
    else {
        imgViewThumb.setImageResource(UIConfig.IMAGE_PLACEHOLDER);
    }

    imgViewThumb.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            Intent i = new Intent(getActivity(), DetailActivity.class);
            i.putExtra("realestate", obj);
            getActivity().startActivity(i);
        }
    });

    String strPrice = String.format("%s %s", obj.getCurrency(), obj.getPrice());
    Spanned spannedPrice = Html.fromHtml(strPrice);
    spannedPrice = Html.fromHtml(spannedPrice.toString());

    Spanned spannedAddress = Html.fromHtml(obj.getAddress());
    spannedAddress = Html.fromHtml(spannedAddress.toString());

    String address = spannedAddress.toString();
    if(address.length() > Config.ELLIPSE_HOME_COUNT)
        address = spannedAddress.toString().substring(0, Config.ELLIPSE_HOME_COUNT) + "...";

    TextView tvTitle = (TextView) viewInflate.findViewById(R.id.tvTitle);
    TextView tvSubtitle = (TextView) viewInflate.findViewById(R.id.tvSubtitle);

    tvTitle.setText(spannedPrice);
    tvSubtitle.setText(address);

    ToggleButton toggleButtonFave = (ToggleButton) viewInflate.findViewById(R.id.toggleButtonFave);
    toggleButtonFave.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            checkFave(v, obj);
        }
    });

    Favorite fave = q.getFavoriteByRealEstateId(obj.getRealestate_id());
    toggleButtonFave.setChecked(true);
    if(fave == null)
        toggleButtonFave.setChecked(false);
}

@Override
public void onMapClick(LatLng point) {
    // TODO Auto-generated method stub
    frameSliding.setVisibility(View.INVISIBLE);
}

private void checkFave(View view, RealEstate realEstate) {

    Queries q = RealEstateApplication.getQueriesInstance(getContext());
    Favorite fave = q.getFavoriteByRealEstateId(realEstate.getRealestate_id());
    if(fave != null) {
        q.deleteFavorite(realEstate.getRealestate_id());
        ((ToggleButton) view).setChecked(false);
    }
    else {
        fave = new Favorite();
        fave.setRealestate_id(realEstate.getRealestate_id());
        q.insertFavorite(fave);
        ((ToggleButton) view).setChecked(true);
    }
}

public void showRefresh(boolean show) {
    swipeRefresh.setRefreshing(show);
    swipeRefresh.setEnabled(show);
}

ArrayList<Marker> markers1;

@SuppressLint("DefaultLocale")
@Override
public void onUserDidFinishDrawPolygon(PolygonOptions polygonOptions) {
    // TODO Auto-generated method stub
    googleMap.clear();
    googleMap.addPolygon( polygonOptions );
    markers1 = getMarkersInsidePoly(polygonOptions, null, markerList);

    markerList.clear();
    markers.clear();
    for(Marker mark1 : markers1) {
        for(RealEstate realEstate : realEstates) {
            String strPrice = String.format("%s %s", realEstate.getCurrency(), realEstate.getPrice());
            if(mark1.getPosition().latitude == realEstate.getLat() &&
                    mark1.getPosition().longitude == realEstate.getLon() &&
                    mark1.getTitle().compareTo(strPrice) == 0) {

                Marker mark = createMarker(realEstate);
                markerList.add(mark);
                markers.put(mark.getId(), realEstate);
                break;
            }
        }
    }
    drawingView.enableDrawing(false);
    drawingView.resetPolygon();
    drawingView.startNew();

    if(markers1.size() == 0)
        Toast.makeText(getContext(), R.string.no_results_found, Toast.LENGTH_SHORT).show();
}

@Override
public void onUserDidFinishDrawPolyline(PolylineOptions polylineOptions) { }

public ArrayList<Marker> getMarkersInsidePoly(PolygonOptions polygonOptions,
                                              PolylineOptions polylineOptions,  ArrayList<Marker> markers) {

    ArrayList<Marker> markersFound = new ArrayList<Marker>();
    for(Marker mark : markers) {
        Boolean isFound = polygonOptions != null ?
                drawingView.latLongContainsInPolygon(mark.getPosition(), polygonOptions) :
                drawingView.latLongContainsInPolyline(mark.getPosition(), polylineOptions);

        if(isFound) {
            markersFound.add(mark);
        }
    }
    return markersFound;
}

@OnClick(R.id.btnDraw)
public void drawMap() {
    drawingView.enableDrawing(true);
    drawingView.startDrawingPolygon(true);
}

@OnClick(R.id.btnRefresh)
public void refresh() {
    showRefresh(true);
    addMarkers(realEstates);
    showRefresh(false);
}

@OnClick(R.id.btnRoute)
public void route() {
    if(selectedRealEstate == null) {
        MGUtilities.showAlertView(
                getActivity(),
                R.string.action_error,
                R.string.cannot_proceed_route);
        return;
    }

    String geo = String.format("http://maps.google.com/maps?f=d&daddr=%s&dirflg=d", selectedRealEstate.getAddress()) ;
    Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(geo));
    intent.setComponent(new ComponentName("com.google.android.apps.maps", "com.google.android.maps.MapsActivity"));
    startActivity(intent);
}

@OnClick(R.id.btnCurrentLocation)
public void currentLocation() {
    Location loc = RealEstateApplication.currentLocation;
    if(loc != null) {
        googleMap.moveCamera(
                CameraUpdateFactory.newLatLngZoom(
                        new LatLng(loc.getLatitude(), loc.getLongitude()),
                        70) );
    }
}

@Override
public void onLocationChanged(Location prevLoc, Location currentLoc) {
    RealEstateApplication app = (RealEstateApplication) getActivity().getApplication();
    app.setOnLocationListener(null, getActivity());
    Handler h = new Handler();
    h.postDelayed(new Runnable() {

        @Override
        public void run() {
            getData();
        }
    }, Config.DELAY_SHOW_ANIMATION + 500);

    googleMap.setMyLocationEnabled(true);
}

@Override
public void onLocationRequestDenied() {
    showRefresh(false);
    MGUtilities.showAlertView(getActivity(), R.string.permission_error, R.string.permission_error_details_location);
}

public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == Config.PERMISSION_REQUEST_LOCATION_SETTINGS) {
        if(MGUtilities.isLocationEnabled(getActivity()))
            refetch();
        else {
            showRefresh(false);
            Toast.makeText(getActivity(), 

  R.string.location_error_not_turned_on, Toast.LENGTH_LONG).show();
        }
    }
}
}

标签: androidgoogle-mapsgoogle-maps-android-api-2

解决方案


推荐阅读