首先将其包含在您的 gradle 应用程序中的依赖项下
compile 'com.google.android.gms:play-services:7.8.0'
然后导入如下
import android.bluetooth.BluetoothAdapter;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
import android.support.design.widget.Snackbar;
import android.support.v4.app.Fragment;
import android.support.v4.content.ContextCompat;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.RecyclerView;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.Toast;
public class OffersFragment extends Fragment {
GoogleMap map;
LatLngBounds visibleLatLngBounds;
LatLng coordinate;
int distanceAway = 5000;
public OffersFragment(){}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_offers, container, false);
MapsInitializer.initialize(getActivity());
realm = Realm.getInstance(getActivity());
setupMap(savedInstanceState);
recyclerView.setLayoutManager(new WrappingLinearLayoutManager(getActivity()));
recyclerView.setNestedScrollingEnabled(false);
recyclerView.setHasFixedSize(false);
swipeRefreshLayout.setColorSchemeResources(R.color.color_primary, R.color.color_accent);
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
refreshOffers();
}
});
ArrayAdapter<CharSequence> kmArrayAdapter = ArrayAdapter
.createFromResource(this.getContext(), R.array.string_array_kilometers_away,
android.R.layout.simple_spinner_item);
kmArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
kmRangeSpinner.setAdapter(kmArrayAdapter);
kmRangeSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
map.clear();
if (coordinate != null) {
if (id == 0) setDistanceAway(5000);
else if (id == 1) setDistanceAway(10000);
else if (id == 2) setDistanceAway(20000);
else if (id == 3) setDistanceAway(50000);
else if (id == 4) setDistanceAway(200000);
}
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
int id = parent.getId();
if (id == 0) setDistanceAway(5000);
else if (id == 1) setDistanceAway(10000);
else if (id == 2) setDistanceAway(20000);
else if (id == 3) setDistanceAway(50000);
else if (id == 4) setDistanceAway(200000);
}
});
ArrayAdapter<CharSequence> categoriesAdapter = ArrayAdapter
.createFromResource(this.getContext(), R.array.string_array_offer_categories,
android.R.layout.simple_spinner_item);
categoriesAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
categoriesSpinner.setAdapter(categoriesAdapter);
categoriesSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
if(visibleLatLngBounds!=null){
try {
map.clear();
loadOffers();
} catch (ParseException e) {
e.printStackTrace();
}
}
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
return view;
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
// Check if device supports Bluetooth Low Energy.
if (!beaconManager.hasBluetooth()) {
Toast.makeText(getActivity(), "Device does not have Bluetooth Low Energy", Toast.LENGTH_LONG).show();
return;
}
// If Bluetooth is not enabled, let user enable it.
if (!beaconManager.isBluetoothEnabled()) {
Snackbar.make(view, "Open Bluetooth Low Energy to discover exclusive offers", Snackbar.LENGTH_LONG).setAction("Discover", new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivity(enableBtIntent);
}
}).show();
}
}
private void setupMap(Bundle savedInstanceState){
mapView.onCreate(savedInstanceState);
// Gets to GoogleMap from the MapView and does initialization stuff
map = mapView.getMap();
map.getUiSettings().setMyLocationButtonEnabled(false);
map.setMyLocationEnabled(true);
map.getUiSettings().setScrollGesturesEnabled(false);
map.getUiSettings().setTiltGesturesEnabled(false);
map.getUiSettings().setRotateGesturesEnabled(false);
map.getUiSettings().setZoomGesturesEnabled(false);
map.setOnMapLoadedCallback(new GoogleMap.OnMapLoadedCallback() {
@Override
public void onMapLoaded() {
visibleLatLngBounds = map.getProjection()
.getVisibleRegion().latLngBounds;
if (visibleLatLngBounds != null) {
try {
loadOffers();
} catch (ParseException e) {
e.printStackTrace();
}
}
}
});
map.setOnCameraChangeListener(new GoogleMap.OnCameraChangeListener() {
@Override
public void onCameraChange(CameraPosition cameraPosition) {
visibleLatLngBounds = map.getProjection()
.getVisibleRegion().latLngBounds;
if (visibleLatLngBounds != null) {
try {
loadOffers();
} catch (ParseException e) {
e.printStackTrace();
}
}
}
});
map.setOnMyLocationChangeListener(new GoogleMap.OnMyLocationChangeListener() {
@Override
public void onMyLocationChange(Location location) {
double lat = location.getLatitude();
double lng = location.getLongitude();
coordinate = new LatLng(lat, lng);
// Updates the location and zoom of the MapView
animateToLocation(coordinate, getDistanceAway());
map.setOnMyLocationChangeListener(null);
}
});
// Needs to call MapsInitializer before doing any CameraUpdateFactory calls
MapsInitializer.initialize(this.getActivity());
Criteria criteria = new Criteria();
LocationManager locationManager = (LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE);
String provider = locationManager.getBestProvider(criteria, false);
if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION},MY_LOCATION_REQUEST_CODE);
}
else{
map.setMyLocationEnabled(true);
}
if (locationManager.getLastKnownLocation(provider)!=null){
Location location = locationManager.getLastKnownLocation(provider);
double lat = location.getLatitude();
double lng = location.getLongitude();
coordinate = new LatLng(lat, lng);
// Updates the location and zoom of the MapView
animateToLocation(coordinate, getDistanceAway());
}
else{
//Zoom in to Nairobi
coordinate = new LatLng(-1.277001, 36.816498);
animateToLocation(coordinate, getDistanceAway());
}
// Marker galleria = map.addMarker(new MarkerOptions().position(GALLERIA)
// .title("Safaricom Shop, Galleria"));
//
// Marker westgate = map.addMarker(new MarkerOptions().position(WESTGATE)
// .title("Safaricom Shop, Westgate"));
}
public void loadOffers() throws ParseException {
RealmResults<Offer> offers;
if(categoriesSpinner.getSelectedItemId()==0){
offers = realm.where(Offer.class).between(Offer.VARIABLE_LATITUDE,visibleLatLngBounds.southwest.latitude,visibleLatLngBounds.northeast.latitude).between(Offer.VARIABLE_LONGITUDE, visibleLatLngBounds.southwest.longitude, visibleLatLngBounds.northeast.longitude).findAll();
}
else {
offers = realm.where(Offer.class).between(Offer.VARIABLE_LATITUDE,visibleLatLngBounds.southwest.latitude,visibleLatLngBounds.northeast.latitude).between(Offer.VARIABLE_LONGITUDE, visibleLatLngBounds.southwest.longitude, visibleLatLngBounds.northeast.longitude).equalTo(Offer.VARIABLE_CATEGORY,categoriesSpinner.getSelectedItemId()).findAll();
}
Log.d(LOG_TAG, "NorthEast latlng:"+visibleLatLngBounds.northeast.latitude+" "+visibleLatLngBounds.northeast.longitude+"SouthWest latlng:"+visibleLatLngBounds.southwest.latitude+" "+visibleLatLngBounds.southwest.longitude);
offersAdapter = new OffersAdapter(getActivity(), offers);
recyclerView.setAdapter(offersAdapter);
for(Offer offer: offers){
map.addMarker(new MarkerOptions().position(new LatLng(offer.getStore().getLatitude(), offer.getStore().getLongitude())).title(offer.getStore().getName()));
}
}
public void refreshOffers(){
String urlJsonArray = "************/viewjsonshopoffers.php";
request = new JsonArrayRequest(urlJsonArray,
new Response.Listener<JSONArray>() {
@Override
public void onResponse(JSONArray response) {
Log.d(LOG_TAG, response.toString());
swipeRefreshLayout.setRefreshing(false);
try {
realm.beginTransaction();
realm.clear(Offer.class);
realm.commitTransaction();
for (int i = 0; i < response.length(); i++) {
JSONObject jsonResponse = (JSONObject) response.get(i);
int storeId = jsonResponse.getInt("shop_id");
String storeName = jsonResponse.getString("shop_name");
String storeStreetName = jsonResponse.getString("shop_streetname");
String storeStreetDesc = jsonResponse.getString("shop_streetdesc");
String storeCity = jsonResponse.getString("shop_city");
double storeLatitude = jsonResponse.getDouble("shop_latitude");
double storeLongitude = jsonResponse.getDouble("shop_longitude");
Store store = new Store(storeId, storeName, storeStreetName, storeStreetDesc, storeCity, storeLatitude, storeLongitude);
int offerId = jsonResponse.getInt("offer_id");
String offerName = jsonResponse.getString("offer_name");
String offerPriceDescription = jsonResponse.getString("offer_string_price_description");
int offerPrice = jsonResponse.getInt("offer_int_price");
String offerDescription = jsonResponse.getString("offer_description");
String offerNotificationMessage = jsonResponse.getString("offer_notification_message");
Date offerDateDue = DateUtils.getDateInMillis(jsonResponse.getString("offer_datedue"));
int offerKeyword = jsonResponse.getInt("offer_keyword");
int offerBeaconMajor = jsonResponse.getInt("offer_beacon_major");
String offerImageUrl = jsonResponse.getString("offer_url");
Offer offer = new Offer(offerId, offerName, offerPriceDescription, offerPrice, offerDescription, offerNotificationMessage, offerDateDue, store, offerKeyword, offerBeaconMajor, offerImageUrl);
realm.beginTransaction();
realm.copyToRealmOrUpdate(offer);
realm.commitTransaction();
map.clear();
loadOffers();
}
} catch (JSONException e) {
e.printStackTrace();
} catch (ParseException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d(LOG_TAG, "Error: " + error.getMessage());
swipeRefreshLayout.setRefreshing(false);
error.printStackTrace();
}
});
AppController.getInstance().addToRequestQueue(request, LOG_TAG);
}
private void animateToLocation(LatLng coordinate, int meters) {
DisplayMetrics displaymetrics = new DisplayMetrics();
if(getActivity().getWindowManager()!=null){
getActivity().getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int width = displaymetrics.widthPixels;
int metersRecalculate = meters *10;
double equatorLength = 40075004; // in meters
double widthInPixels = width;
double metersPerPixel = equatorLength / 256;
int zoomLevel = 1;
while ((metersPerPixel * widthInPixels) > metersRecalculate) {
metersPerPixel /= 2;
++zoomLevel;
}
CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(coordinate, zoomLevel);
map.animateCamera(cameraUpdate);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == MY_LOCATION_REQUEST_CODE) {
if (permissions.length == 1 &&
permissions[0] == Manifest.permission.ACCESS_FINE_LOCATION &&
grantResults[0] == PackageManager.PERMISSION_GRANTED) {
map.setMyLocationEnabled(true);
} else {
// Permission was denied. Display an error message.
}
}
}
public int getDistanceAway() {
return distanceAway;
}
public void setDistanceAway(int distanceAway) {
this.distanceAway = distanceAway;
animateToLocation(coordinate, this.distanceAway);
}
@Override
public void onResume() {
mapView.onResume();
super.onResume();
}
@Override
public void onDestroy() {
super.onDestroy();
mapView.onDestroy();
if(request!=null){
request.cancel();
}
}
@Override
public void onLowMemory() {
super.onLowMemory();
mapView.onLowMemory();
}
}
我没有编辑太多,因为这个项目有一个场景 f 找到当前位置,并要求用户在获取用户的最后一个位置时更新他的位置。
对于那些使用 Realm 的人也可以从这个项目中受益,其中 Realm 与地图一起使用