我在SupportMapFragment
内使用fragment
,第一次,地图显示,但第二次我去了那个片段,地图变白了,没有显示。
我尝试了多种解决方案,包括:删除之前的fragment
,覆盖onDestroy()
和onPause()
,但是徒劳无功。
一个简单的问题:我应该使用MapView
代替SupportMapFragment
吗?
任何帮助都会受到赞赏,因为我已经挣扎了好几天。
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
if (view != null) {
ViewGroup parent = (ViewGroup) view.getParent();
if (parent != null)
parent.removeView(view);
}
try {
view = inflater.inflate(R.layout.rider_fragment_home, container, false);
} catch (InflateException e) {
}
return view;
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle
savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mapFragment = (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map);
mapFragment.onCreate(savedInstanceState);
mapFragment.getMapAsync(this);
setUpLocation();
}
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
mMap.setIndoorEnabled(false);
mMap.setTrafficEnabled(false);
mMap.setBuildingsEnabled(false);
mMap.getUiSettings().setZoomControlsEnabled(true);
}
private void displayLocation() {
if (ActivityCompat.checkSelfPermission(getActivity().getBaseContext(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
ActivityCompat.checkSelfPermission(getActivity().getBaseContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
if (mGoogleApiClient != null) {
Common.mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if ( Common.mLastLocation != null) {
final double latitude = Common.mLastLocation.getLatitude();
final double longitude = Common.mLastLocation.getLongitude();
//update to database (TO_DO)
if (mCurrent != null) {
mCurrent.remove(); // remove actual marker
}
mCurrent = mMap.addMarker(new MarkerOptions()
.icon(BitmapDescriptorFactory.fromResource(R.drawable.driver_marker))
.position(new LatLng(latitude, longitude))
.title("You"));
//move camera to the new position
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(latitude, longitude), 7.0f));
}
}
}
private void startLocationUpdates() {
//ACCESS_COARSE_LOCATION : approximate location
//ACCESS_FINE_LOCATION : exact location
if (ActivityCompat.checkSelfPermission(getActivity().getBaseContext(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
ActivityCompat.checkSelfPermission(getActivity().getBaseContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
if (mGoogleApiClient != null) {
//requestLactionUpdates : register the current activity to be updated periodically
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}
}
@Override
public void onConnected(@Nullable Bundle bundle) {
displayLocation();
startLocationUpdates();
}
@Override
public void onConnectionSuspended(int i) {
mGoogleApiClient.connect();
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
}
@Override
public void onLocationChanged(Location location) {
Common.mLastLocation = location;
displayLocation();
if (Common.mLastLocation != null) {
new LocationService().LocationUser(getActivity(), Common.mLastLocation.getLatitude() + "", Common.mLastLocation.getLongitude() + "", LoginFragment.user.getUserID());
//update last seen location
String lat = String.valueOf(Common.mLastLocation.getLatitude());
String lng = String.valueOf(Common.mLastLocation.getLongitude());
}
}
@Override
public void onDetach() {
super.onDetach();
try {
Field childFragmentManager = Fragment.class
.getDeclaredField("mChildFragmentManager");
childFragmentManager.setAccessible(true);
childFragmentManager.set(this, null);
} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
@Override
public void onResume() {
super.onResume();
mapFragment.onResume();
}
@Override
public void onPause() {
super.onPause();
mapFragment.onPause();
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode) {
case MY_PERMISSION_REQUEST_CODE:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
if (checkPlayServices()) {
buildGoogleApiClient();
createLocationRequest();
displayLocation();
}
}
}
}
private void setUpLocation() {
if (ActivityCompat.checkSelfPermission(getActivity().getBaseContext(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
ActivityCompat.checkSelfPermission(getActivity().getBaseContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(getActivity(), new String[]{
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION
}, MY_PERMISSION_REQUEST_CODE);
} else {
if (checkPlayServices()) {
buildGoogleApiClient();
createLocationRequest();
displayLocation();
}
}
}
private void createLocationRequest() {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(UPDATE_INTERVAL);
mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setSmallestDisplacement(DISPLACEMENT);
}
private void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(getActivity())
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
mGoogleApiClient.connect();
}
private boolean checkPlayServices() {
int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getActivity().getApplicationContext());
if (resultCode != ConnectionResult.SUCCESS) {
if (GooglePlayServicesUtil.isUserRecoverableError(resultCode)) {
//if their is an error and it's recoverable , an error dialog is shown to tell the user about error and direct them to playStore if Google Play services is out of date or missing
GooglePlayServicesUtil.getErrorDialog(resultCode, getActivity(), PLAY_SERVICE_RES_REQUEST).show();
} else {
Toast.makeText(getActivity().getApplicationContext(), "This device is not supported", Toast.LENGTH_SHORT).show();
}
return false;
}
return true;
}
答案 0 :(得分:0)
尝试使用Fragment.java
inflate if null
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (view == null)
{
view = inflater.inflate(R.layout.rider_fragment_home, container, false);
}
mapFragment = (SupportMapFragment) this.getChildFragmentManager().findFragmentById(R.id.map);
mapFragment.onCreate(savedInstanceState);
mapFragment.getMapAsync(this);
setUpLocation();
return view;
}
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
mMap.setIndoorEnabled(false);
mMap.setTrafficEnabled(false);
mMap.setBuildingsEnabled(false);
mMap.getUiSettings().setZoomControlsEnabled(true);
}
答案 1 :(得分:-1)
<fragment
android:id="@+id/maplocation"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
public class LocationFragment extends Fragment implements GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,
LocationListener {
private SupportMapFragment mapFragment;
private GoogleMap map;
private GoogleApiClient mGoogleApiClient;
ArrayList markerPoints;
private LocationRequest mLocationRequest;
private long UPDATE_INTERVAL = 15000; /* 15 secs */
private long FASTEST_INTERVAL = 5000; /* 5 secs */
private final static int CONNECTION_FAILURE_RESOLUTION_REQUEST = 9000;
private AVLoadingIndicatorView progressBar;
private static View view;
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
if (view != null) {
ViewGroup parent = (ViewGroup) view.getParent();
if (parent != null)
parent.removeView(view);
}
try {
view = inflater.inflate(R.layout.location_fragment, container, false);
} catch (InflateException e) {
}
markerPoints = new ArrayList();
mapFragment = ((SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.maplocation));
if (mapFragment != null) {
mapFragment.getView().setClickable(false);
mapFragment.getMapAsync(new OnMapReadyCallback() {
@Override
public void onMapReady(GoogleMap map) {
loadMap(map);
}
});
} else {
Toast.makeText(getActivity(), getResources().getString(R.string.Error_Map_Fragment_was_null), Toast.LENGTH_SHORT).show();
}
mGoogleApiClient = new GoogleApiClient.Builder(getActivity())
// The next two lines tell the new client that “this” current class will handle connection stuff
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
//fourth line adds the LocationServices API endpoint from GooglePlayServices
.addApi(LocationServices.API)
.build();
// Create the LocationRequest object
mLocationRequest = LocationRequest.create()
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
.setInterval(1000 * 1000) // 10 seconds, in milliseconds
.setFastestInterval(1000 * 1000); // 1 second, in milliseconds
// mGoogleApiClient.connect();
setRetainInstance(true);
return view;
}
protected void loadMap(GoogleMap googleMap) {
map = googleMap;
if (map != null) {
// Map is ready
Toast.makeText(getActivity(), getResources().getString(R.string.Map_Fragment_was_loaded_properly), Toast.LENGTH_SHORT).show();
map.setMyLocationEnabled(true);
map.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
@Override
public void onMapClick(LatLng point) {
//onMapTouch(point);
}
});
} else {
if(isAdded()){
Toast.makeText(getActivity(), getResources().getString(R.string.Error_Map_was_nul), Toast.LENGTH_SHORT).show();
}
}
}
/*
* Called when the Activity becomes visible.
*/
@Override
public void onStart() {
super.onStart();
}
/*
* Called when the Activity is no longer visible.
*/
@Override
public void onStop() {
// Disconnecting the client invalidates it.
if (mGoogleApiClient != null) {
mGoogleApiClient.disconnect();
}
super.onStop();
}
/*
* Handle results returned to the FragmentActivity by Google Play services
*/
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
// Decide what to do based on the original request code
switch (requestCode) {
case CONNECTION_FAILURE_RESOLUTION_REQUEST:
/*
* If the result code is Activity.RESULT_OK, try to connect again
*/
switch (resultCode) {
case Activity.RESULT_OK:
mGoogleApiClient.connect();
break;
}
}
}
// Fetches data from url passed
private boolean isGooglePlayServicesAvailable() {
// Check that Google Play services is available
int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getActivity());
// If Google Play services is available
if (ConnectionResult.SUCCESS == resultCode) {
// In debug mode, log the status
Log.d("Location Updates", "Google Play services is available.");
return true;
} else {
// Get the error dialog from Google Play services
Dialog errorDialog = GooglePlayServicesUtil.getErrorDialog(resultCode, getActivity(),
CONNECTION_FAILURE_RESOLUTION_REQUEST);
// If Google Play services can provide an error dialog
if (errorDialog != null) {
// Create a new DialogFragment for the error dialog
ErrorDialogFragment errorFragment = new ErrorDialogFragment();
errorFragment.setDialog(errorDialog);
errorFragment.show(getFragmentManager(), "Location Updates");
}
return false;
}
}
/*
* Called by Location Services when the request to connect the client
* finishes successfully. At this point, you can request the current
* location or start periodic updates
*/
@Override
public void onConnected(Bundle dataBundle) {
// Display the connection status
Location location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (location != null) {
if (isAdded()) {
Toast.makeText(getActivity(), getResources().getString(R.string.GPS_location_was_found), Toast.LENGTH_SHORT).show();
}
LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(latLng, 6);
map.animateCamera(cameraUpdate);
// Marker marker = map.addMarker(new MarkerOptions().position(latLng).app_icon(BitmapDescriptorFactory.fromResource(R.mipmap.ic_launcher)).flat(true).anchor(0.5f,0.5f));
onMapTouch(latLng);
LatLng latLng1 = new LatLng("your latitude", "your longitude");
onMapTouch(latLng1);
startLocationUpdates();
} else {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
if(isAdded()){
Toast.makeText(getActivity(), getResources().getString(R.string.Current_location_was_nullenable_GPS_on_emulator), Toast.LENGTH_SHORT).show();
}
}
}
protected void startLocationUpdates() {
mLocationRequest = new LocationRequest();
mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
mLocationRequest.setInterval(UPDATE_INTERVAL);
mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
//LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, (LocationListener) getActivity());
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient,
mLocationRequest, this);
}
/*
* Called by Location Services if the connection to the location client
* drops because of an error.
*/
@Override
public void onConnectionSuspended(int i) {
if (i == CAUSE_SERVICE_DISCONNECTED) {
Toast.makeText(getActivity(), getResources().getString(R.string.Disconnected_Please_reconnect), Toast.LENGTH_SHORT).show();
} else if (i == CAUSE_NETWORK_LOST) {
Toast.makeText(getActivity(), getResources().getString(R.string.Network_lost_Please_reconnect), Toast.LENGTH_SHORT).show();
}
}
/*
* Called by Location Services if the attempt to Location Services fails.
*/
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
/*
* Google Play services can resolve some errors it detects. If the error
* has a resolution, try sending an Intent to start a Google Play
* services activity that can resolve error.
*/
if (connectionResult.hasResolution()) {
try {
// Start an Activity that tries to resolve the error
connectionResult.startResolutionForResult(getActivity(),
CONNECTION_FAILURE_RESOLUTION_REQUEST);
/*
* Thrown if Google Play services canceled the original
* PendingIntent
*/
} catch (IntentSender.SendIntentException e) {
// Log the error
e.printStackTrace();
}
} else {
if (isAdded()) {
Toast.makeText(getActivity(), getResources().getString(R.string.Sorry_Location_services_not_available_t_oyou), Toast.LENGTH_LONG).show();
}
}
}
@Override
public void onLocationChanged(Location location) {
LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
/* if (marker == null) {
marker.remove();
marker = map.addMarker(new MarkerOptions().position(latLng).app_icon(BitmapDescriptorFactory.fromResource(R.drawable.vehicle_marker)));
}
marker.setPosition(latLng);*/
CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(latLng, 14);
map.animateCamera(cameraUpdate);
String msg = "Updated Location: " +
Double.toString(location.getLatitude()) + "," +
Double.toString(location.getLongitude());
// Toast.makeText(getActivity(), msg, Toast.LENGTH_SHORT).show();
}
// Define a DialogFragment that displays the error dialog
public static class ErrorDialogFragment extends DialogFragment {
// Global field to contain the error dialog
private Dialog mDialog;
// Default constructor. Sets the dialog field to null
public ErrorDialogFragment() {
super();
mDialog = null;
}
// Set the dialog to display
public void setDialog(Dialog dialog) {
mDialog = dialog;
}
// Return a Dialog to the DialogFragment.
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return mDialog;
}
}
// Fetches data from url passed
private class DownloadTask extends AsyncTask<String, Void, String> {
// Downloading data in non-ui thread
@Override
protected String doInBackground(String... url) {
// For storing data from web service
String data = "";
try {
// Fetching the data from web service
data = downloadUrl(url[0]);
} catch (Exception e) {
Log.d("Background Task", e.toString());
}
return data;
}
// Executes in UI thread, after the execution of
// doInBackground()
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
ParserTask parserTask = new ParserTask();
// Invokes the thread for parsing the JSON data
parserTask.execute(result);
}
}
/**
* A class to parse the Google Places in JSON format
*/
private class ParserTask extends AsyncTask<String, Integer, List<List<HashMap<String, String>>>> {
// Parsing the data in non-ui thread
@Override
protected List<List<HashMap<String, String>>> doInBackground(String... jsonData) {
JSONObject jObject;
List<List<HashMap<String, String>>> routes = null;
try {
jObject = new JSONObject(jsonData[0]);
DirectionsJSONParser parser = new DirectionsJSONParser();
// Starts parsing data
routes = parser.parse(jObject);
} catch (Exception e) {
e.printStackTrace();
}
return routes;
}
// Executes in UI thread, after the parsing process
@Override
protected void onPostExecute(List<List<HashMap<String, String>>> result) {
ArrayList points = null;
PolylineOptions lineOptions = null;
MarkerOptions markerOptions = new MarkerOptions();
// Traversing through all the routes
for (int i = 0; i < result.size(); i++) {
points = new ArrayList();
lineOptions = new PolylineOptions();
// Fetching i-th route
List<HashMap<String, String>> path = result.get(i);
// Fetching all the points in i-th route
for (int j = 0; j < path.size(); j++) {
HashMap<String, String> point = path.get(j);
double lat = Double.parseDouble(point.get("lat"));
double lng = Double.parseDouble(point.get("lng"));
LatLng position = new LatLng(lat, lng);
points.add(position);
}
// Adding all the points in the route to LineOptions
lineOptions.addAll(points);
lineOptions.width(12);
lineOptions.color(Color.RED);
lineOptions.geodesic(true);
}
// Drawing polyline in the Google Map for the i-th route
map.addPolyline(lineOptions);
}
}
private String getDirectionsUrl(LatLng origin, LatLng dest) {
// Origin of route
String str_origin = "origin=" + origin.latitude + "," + origin.longitude;
// Destination of route
String str_dest = "destination=" + dest.latitude + "," + dest.longitude;
// Sensor enabled
String sensor = "sensor=false";
// Building the parameters to the web service
String parameters = str_origin + "&" + str_dest + "&" + sensor;
// Output format
String output = "json";
// Building the url to the web service
String url = "https://maps.googleapis.com/maps/api/directions/" + output + "?" + parameters;
return url;
}
/**
* A method to download json data from url
*/
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("Excep downloading url", e.toString());
} finally {
iStream.close();
urlConnection.disconnect();
}
return data;
}
private void onMapTouch(LatLng point) {
// Already two locations
if (markerPoints.size() > 1) {
markerPoints.clear();
map.clear();
}
// Adding new item to the ArrayList
markerPoints.add(point);
// Creating MarkerOptions
MarkerOptions options = new MarkerOptions();
// Setting the position of the marker
options.position(point);
/**
* For the start location, the color of marker is GREEN and
* for the end location, the color of marker is RED.
*/
if (markerPoints.size() == 1) {
options.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN));
} else if (markerPoints.size() == 2) {
options.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED));
}
// Add new marker to the Google Map Android API V2
map.addMarker(options);
// Checks, whether start and end locations are captured
if (markerPoints.size() >= 2) {
LatLng origin = (LatLng) markerPoints.get(0);
LatLng dest = (LatLng) markerPoints.get(1);
// Getting URL to the Google Directions API
String url = getDirectionsUrl(origin, dest);
DownloadTask downloadTask = new DownloadTask();
// Start downloading json data from Google Directions API
downloadTask.execute(url);
}
}}