显示Google Map Fragment中的当前位置 [英] Show Current Location inside Google Map Fragment

查看:93
本文介绍了显示Google Map Fragment中的当前位置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在制作带有谷歌地图的片段。一旦用户访问该片段,他的地图应该放大并聚焦于他的位置。但是,它显示了世界地图,而不是附近的位置(靠近用户):

  @SuppressWarnings(未使用)
public class DeferredMapFragment extends MapFragment implements GoogleMap.OnCameraChangeListener,OnMapReadyCallback,GoogleApiClient.ConnectionCallbacks,GoogleApiClient.OnConnectionFailedListener,
LocationListener {
private static final String TAG =DeferredMapFragment;

private Deque< Runnable> pendingActions;
私有AbstractMap<标记,对象>标签;

私人GoogleMap地图;
private LocationRequest mLocationRequest;
私有GoogleApiClient mGoogleApiClient;
私人位置mLastLocation;
私人标记标记;

私有GoogleMap.OnCameraChangeListener cameraChangeListener = null;

private boolean isMapReady = false;

/ *
* INTERNALS
* /

@Override
public void onActivityCreated(Bundle savedInstanceState){
super。 onActivityCreated(savedInstanceState);

if(getMap()!= null){
map = getMap();
getMap()。setOnCameraChangeListener(this);
}
}

@Override
public void onCameraChange(CameraPosition cameraPosition){
isMapReady = true;

if(pendingActions!= null){
int i = pendingActions.size();
while(i> 0){
pendingActions.pop()。run();
--i;



if(cameraChangeListener!= null){
cameraChangeListener.onCameraChange(cameraPosition);
}

if(getMap()!= null){
getMap()。setOnCameraChangeListener(cameraChangeListener);



private void execute(Runnable action){
if(action == null){
return;
}

if(isMapReady){
action.run();
} else {
if(pendingActions == null){
pendingActions = new LinkedList<>();
}
pendingActions.add(action);


$ b $ * b $ b * TAGGING
* /

private void addTag(标记键,对象值) {
if(tags == null){
tags = new HashMap<>();
}
tags.put(key,value);
}

public Object getTag(Marker key){
return tags!= null? tags.get(key):null;

$ b $ * b $ b * LISTENERS
* /

public void setOnInfoWindowClickListener(final GoogleMap.OnInfoWindowClickListener listener){
执行(new Runnable(){
@Override
public void run(){
getMap()。setOnInfoWindowClickListener(listener);
}
});
}

public void setOnCameraChangeListener(final GoogleMap.OnCameraChangeListener listener){
cameraChangeListener = listener;

$ b $ public void setOnMarkerClickListener(final GoogleMap.OnMarkerClickListener listener){
execute(new Runnable(){
@Override
public void run() {
getMap()。setOnMarkerClickListener(listener);
}
});

$ b $ public void setOnMapClickListener(final GoogleMap.OnMapClickListener listener){
execute(new Runnable(){
@Override
public void run() {
getMap()。setOnMapClickListener(listener);
}
});

$ b $ * b $ b * MAP覆盖
* /

public void addPolyline(final PolylineOptions options){
execute (new Runnable(){
@Override
public void run(){
getMap()。addPolyline(options);
}
});

$ b public void addPolygon(final PolygonOptions options){
execute(new Runnable(){
@Override
public void run(){
getMap()。addPolygon(options);
}
});

$ b $ public void addCircle(final CircleOptions options){
execute(new Runnable(){
@Override
public void run(){
getMap()。addCircle(options);
}
});
}

public void addMarker(final MarkerOptions options){
addMarker(options,null);

$ b $ public void addMarker(final MarkerOptions options,final Object tag){
execute(new Runnable(){
@Override
public void run (){
Marker marker = getMap()。addMarker(options);
if(tag!= null){
addTag(marker,tag);
}
}
});

$ b public void addGroundOverlay(final GroundOverlayOptions options){
execute(new Runnable(){
@Override
public void run(){
getMap()。addGroundOverlay(options);
}
});

$ b $ public void addTileOverlay(final TileOverlayOptions options){
execute(new Runnable(){
@Override
public void run(){
getMap()。addTileOverlay(options);
}
});

$ b $ * b $ b * UI设置
* /
public void setMapToolbarEnabled(final boolean enabled){
execute(new Runnable( ){
@Override
public void run(){
getMap()。getUiSettings()。setMapToolbarEnabled(enabled);
}
});

$ b $ public void setPadding(final int left,final int top,final int right,final int bottom){
execute(new Runnable(){
@覆盖
public void run(){
getMap()。setPadding(left,top,right,bottom);
}
});

$ b $ public void setZoomControlsEnabled(final boolean enabled){
execute(new Runnable(){
@Override
public void run(){
getMap()。getUiSettings()。setZoomControlsEnabled(enabled);
}
});

$ b public void setCompassEnabled(final boolean enabled){
execute(new Runnable(){
@Override
public void run(){
getMap()。getUiSettings()。setCompassEnabled(enabled);
}
});
}

public void setMyLocationButtonEnabled(final boolean enabled){
execute(new Runnable(){
@Override
public void run(){
getMap()。getUiSettings()。setMyLocationButtonEnabled(enabled);
}
});

$ b $ public void setIndoorLevelPickerEnabled(final boolean enabled){
execute(new Runnable(){
@Override
public void run(){
getMap()。getUiSettings()。setIndoorLevelPickerEnabled(enabled);
}
});

$ b $ public void setScrollGesturesEnabled(final boolean enabled){
execute(new Runnable(){
@Override
public void run(){
getMap()。getUiSettings()。setScrollGesturesEnabled(enabled);
}
});

$ b $ public void setZoomGesturesEnabled(final boolean enabled){
execute(new Runnable(){
@Override
public void run(){
getMap()。getUiSettings()。setZoomGesturesEnabled(enabled);
}
});

$ b $ public void setTiltGesturesEnabled(final boolean enabled){
execute(new Runnable(){
@Override
public void run(){
getMap()。getUiSettings()。setTiltGesturesEnabled(enabled);
}
});

$ b $ public void setRotateGesturesEnabled(final boolean enabled){
execute(new Runnable(){
@Override
public void run(){
getMap()。getUiSettings()。setRotateGesturesEnabled(enabled);
}
});
}

public void setAllGesturesEnabled(final boolean enabled){
execute(new Runnable(){
@Override
public void run(){
getMap()。getUiSettings()。setAllGesturesEnabled(enabled);
}
});

$ b $ public void setInfoWindowAdapter(final GoogleMap.InfoWindowAdapter adapter){
execute(new Runnable(){
@Override
public void run() {
getMap()。setInfoWindowAdapter(adapter);
}
});
}

@Override
public void onMapReady(GoogleMap googleMap){

map = googleMap;

setUpMap();


$ b public void setUpMap(){

map.setMapType(GoogleMap.MAP_TYPE_HYBRID);
if(ActivityCompat.checkSelfPermission(getContext(),Manifest.permission.ACCESS_FINE_LOCATION)!= PackageManager.PERMISSION_GRANTED&&&&& ActivityCompat.checkSelfPermission(getContext(),Manifest.permission.ACCESS_COARSE_LOCATION)!= PackageManager.PERMISSION_GRANTED){
// TODO:考虑调用
// ActivityCompat#requestPermissions
//在这里请求丢失的权限,然后覆盖
// public void onRequestPermissionsResult(int requestCode,String [ ]权限,
// int [] grantResults)
//处理用户授予权限的情况。有关更多详细信息,请参阅文档
//获取ActivityCompat#requestPermissions。
return;
}
map.setMyLocationEnabled(true);


@Override
public void onConnected(Bundle bundle){

mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(1000);
mLocationRequest.setFastestInterval(1000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);

//mLocationRequest.setSmallestDisplacement(0.1F);

if(ActivityCompat.checkSelfPermission(getContext(),Manifest.permission.ACCESS_FINE_LOCATION)!= PackageManager.PERMISSION_GRANTED&&& ActivityCompat.checkSelfPermission(getContext(),Manifest.permission.ACCESS_COARSE_LOCATION)!= PackageManager .PERMISSION_GRANTED){
// TODO:考虑调用
// ActivityCompat#requestPermissions
//在这里请求丢失的权限,然后覆盖
// public void onRequestPermissionsResult(int requestCode,String []权限,
// int [] grantResults)
//处理用户授予权限的情况。有关更多详细信息,请参阅文档
//获取ActivityCompat#requestPermissions。
return;
}
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient,mLocationRequest,this);
}

@Override
public void onConnectionSuspended(int i){

}

@Override
public void onLocationChanged(Location location){
mLastLocation = location;

//删除以前的当前位置标记
if(marker!= null){
marker.remove();
}

double dLatitude = mLastLocation.getLatitude();
double dLongitude = mLastLocation.getLongitude();
marker = map.addMarker(new MarkerOptions()。position(new LatLng(dLatitude,dLongitude))
.title(My Location)。icon(BitmapDescriptorFactory
.defaultMarker(BitmapDescriptorFactory。 HUE_RED)));
map.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(dLatitude,dLongitude),8));


$ b $ @Override
public void onPause(){
super.onPause();
if(mGoogleApiClient!= null){
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient,this);



protected synchronized buildGoogleApiClient(){
mGoogleApiClient = new GoogleApiClient.Builder(getContext())
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}

@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult){

}

}

是否有缩放功能?我的API也允许我访问用户的邮政编码。我可以用它来代替吗?我需要用户将他的附近地点显示出来。

.com / a / 34582595/4409409>其他答案在这里,但是,这是不同的,因为你扩展了MapFragment,并且你的自定义行为在Fragment中实现。



这是一个扩展SupportMapFragment的示例片段,它在启动时会获取用户的当前位置,放置标记并放大:

<$ p $ b $ public class MapFragment extends SupportMapFragment
实现OnMapReadyCallback,
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,
LocationListener {

GoogleMap mGoogleMap;
SupportMapFragment mapFrag;
LocationRequest mLocationRequest;
GoogleApiClient mGoogleApiClient;
位置mLastLocation;
标记mCurrLocationMarker;

@Override
public void onResume(){
super.onResume();

setUpMapIfNeeded();

$ b $ private void setUpMapIfNeeded(){

if(mGoogleMap == null){
getMapAsync(this);


@Override
public void onPause(){
super.onPause();

//当Activity不再有效时停止位置更新
if(mGoogleApiClient!= null){
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient,this);



@Override
public void onMapReady(GoogleMap googleMap)
{
mGoogleMap = googleMap;
mGoogleMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);

//初始化Google Play服务
if(android.os.Build.VERSION.SDK_INT> = Build.VERSION_CODES.M){
if(ContextCompat.checkSelfPermission(getActivity (),
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED){
//位置权限已被授予
buildGoogleApiClient();
mGoogleMap.setMyLocationEnabled(true);
} else {
//请求位置权限
checkLocationPermission();
}
}
else {
buildGoogleApiClient();
mGoogleMap.setMyLocationEnabled(true);



protected synchronized buildGoogleApiClient(){
mGoogleApiClient = new GoogleApiClient.Builder(getActivity())
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
mGoogleApiClient.connect();
}

@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(getActivity(),
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED){
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient,mLocationRequest,this );



@Override
public void onConnectionSuspended(int i){}

@Override
public void onConnectionFailed (ConnectionResult connectionResult){}

@Override
public void onLocationChanged(Location location)
{
mLastLocation = location;
if(mCurrLocationMarker!= null){
mCurrLocationMarker.remove();
}

//放置当前位置标记
LatLng latLng = new LatLng(location.getLatitude(),location.getLongitude());
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(latLng);
markerOptions.title(当前位置);
markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA));
mCurrLocationMarker = mGoogleMap.addMarker(markerOptions);

//移动地图相机
mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng,11));

}

public static final int MY_PERMISSIONS_REQUEST_LOCATION = 99;
private void checkLocationPermission(){
if(ContextCompat.checkSelfPermission(getActivity(),Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED){

/ /我们应该显示一个解释吗?
if(ActivityCompat.shouldShowRequestPermissionRationale(getActivity(),
Manifest.permission.ACCESS_FINE_LOCATION)){

//异步显示给用户的解释* - 不要阻止
//此线程正在等待用户的响应!在用户
//看到解释后,再次尝试请求权限。
新的AlertDialog.Builder(getActivity())
.setTitle(需要位置权限)
.setMessage(此应用程序需要位置权限,请接受使用位置功能)
.setPositiveButton(OK,new DialogInterface.OnClickListener(){
@Override $ b $ public void onClick(DialogInterface dialogInterface,int i){
//解释后提示用户已显示
ActivityCompat.requestPermissions(getActivity(),
new String [] {Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_LOCATION);
}
})
.create()
.show();


}其他{
//无需解释,我们可以申请许可。
ActivityCompat.requestPermissions(getActivity(),
new String [] {Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_LOCATION);
}
}
}

@Override
public void onRequestPermissionsResult(int requestCode,
String permissions [],int [] grantResults) {
switch(requestCode){
case MY_PERMISSIONS_REQUEST_LOCATION:{
//如果请求被取消,结果数组为空。
if(grantResults.length> 0
&&& amp; grantResults [0] == PackageManager.PERMISSION_GRANTED){

//许可被授予,yay!做你需要做的
//位置相关的任务。
if(mComboBox.checkSelfPermission(getActivity(),
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED){

if(mGoogleApiClient == null) {
buildGoogleApiClient();
}
mGoogleMap.setMyLocationEnabled(true);
}

} else {

// permission denied,boo!禁用依赖此权限的
//功能。
Toast.makeText(getActivity(),permission denied,Toast.LENGTH_LONG).show();
}
return;
}

//其他'case'行检查其他
//权限此应用可能请求
}
}






$ b

由于位置权限请求需要通过活动,因此您需要路由从Activity到片段的 onRequestPermissionsResult()方法:公共类MainActivity扩展AppCompatActivity {

MapFragment mapFragment;

@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
工具栏工具栏=(工具栏)findViewById(R.id.toolbar);
setSupportActionBar(toolbar);

mapFragment = new MapFragment();

FragmentTransaction transaction = getSupportFragmentManager()。beginTransaction();
transaction.add(R.id.mapframe,mapFragment);
transaction.commit();

$ b @Override
public void onRequestPermissionsResult(int requestCode,
String permissions [],int [] grantResults){
if(requestCode == MapFragment.MY_PERMISSIONS_REQUEST_LOCATION){
mapFragment.onRequestPermissionsResult(requestCode,permissions,grantResults);
}
else {
super.onRequestPermissionsResult(requestCode,permissions,grantResults);



$ b

布局只包含一个FrameLayout,MapFragment就是这样。



activity_main.xml:

 <?xml version =1.0encoding =utf-8?> 
< android.support.design.widget.CoordinatorLayout xmlns:android =http://schemas.android.com/apk/res/android
xmlns:app =http:// schemas .android.com / apk / res-auto
xmlns:tools =http://schemas.android.com/tools
android:layout_width =match_parent
android:layout_height =match_parent
android:fitsSystemWindows =true
tools:context =com.danielnugent.mapapplication.MainActivity>

< android.support.design.widget.AppBarLayout
android:layout_width =match_parent
android:layout_height =wrap_content
android:theme = @风格/ AppTheme.AppBarOverlay>

< android.support.v7.widget.Toolbar
android:id =@ + id / toolbar
android:layout_width =match_parent
android :layout_height =?attr / actionBarSize
android:background =?attr / colorPrimary
app:popupTheme =@ style / AppTheme.PopupOverlay/>

< /android.support.design.widget.AppBarLayout>

< FrameLayout
android:id =@ + id / mapframe
android:layout_marginTop =?attr / actionBarSize
android:layout_height =match_parent
android:layout_width =match_parent/>

结果
<第一个提示输入位置权限:





授予位置权限后,用标记显示当前位置:



如果用户曾拒绝或撤销位置权限,则会在应用程序启动时显示:

首先,解释:

>

然后,位置权限请求:




I am currently working on a Fragment with a Google Map in it. Once a user visits that fragment his map should zoom and focus on his location. However, it shows map of the world and not nearby location (near user):

@SuppressWarnings("unused")
public class DeferredMapFragment extends MapFragment implements GoogleMap.OnCameraChangeListener, OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener,
            LocationListener {
        private static final String TAG = "DeferredMapFragment";

    private Deque<Runnable> pendingActions;
    private AbstractMap<Marker, Object> tags;

    private GoogleMap map;
    private LocationRequest mLocationRequest;
    private GoogleApiClient mGoogleApiClient;
    private Location mLastLocation;
    private Marker marker;

    private GoogleMap.OnCameraChangeListener cameraChangeListener = null;

    private boolean isMapReady = false;

    /*
     * INTERNALS
     */

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        if (getMap() != null) {
            map = getMap();
            getMap().setOnCameraChangeListener(this);
        }
    }

    @Override
    public void onCameraChange(CameraPosition cameraPosition) {
        isMapReady = true;

        if (pendingActions != null) {
            int i = pendingActions.size();
            while (i > 0) {
                pendingActions.pop().run();
                --i;
            }
        }

        if (cameraChangeListener != null) {
            cameraChangeListener.onCameraChange(cameraPosition);
        }

        if (getMap() != null) {
            getMap().setOnCameraChangeListener(cameraChangeListener);
        }
    }

    private void execute(Runnable action) {
        if (action == null) {
            return;
        }

        if (isMapReady) {
            action.run();
        } else {
            if (pendingActions == null) {
                pendingActions = new LinkedList<>();
            }
            pendingActions.add(action);
        }
    }

    /*
     * TAGGING
     */

    private void addTag(Marker key, Object value) {
        if (tags == null) {
            tags = new HashMap<>();
        }
        tags.put(key, value);
    }

    public Object getTag(Marker key) {
        return tags != null ? tags.get(key) : null;
    }

    /*
     * LISTENERS
     */

    public void setOnInfoWindowClickListener(final GoogleMap.OnInfoWindowClickListener listener) {
        execute(new Runnable() {
            @Override
            public void run() {
                getMap().setOnInfoWindowClickListener(listener);
            }
        });
    }

    public void setOnCameraChangeListener(final GoogleMap.OnCameraChangeListener listener) {
        cameraChangeListener = listener;
    }

    public void setOnMarkerClickListener(final GoogleMap.OnMarkerClickListener listener) {
        execute(new Runnable() {
            @Override
            public void run() {
                getMap().setOnMarkerClickListener(listener);
            }
        });
    }

    public void setOnMapClickListener(final GoogleMap.OnMapClickListener listener) {
        execute(new Runnable() {
            @Override
            public void run() {
                getMap().setOnMapClickListener(listener);
            }
        });
    }

    /*
     * MAP OVERLAYS
     */

    public void addPolyline(final PolylineOptions options) {
        execute(new Runnable() {
            @Override
            public void run() {
                getMap().addPolyline(options);
            }
        });
    }

    public void addPolygon(final PolygonOptions options) {
        execute(new Runnable() {
            @Override
            public void run() {
                getMap().addPolygon(options);
            }
        });
    }

    public void addCircle(final CircleOptions options) {
        execute(new Runnable() {
            @Override
            public void run() {
                getMap().addCircle(options);
            }
        });
    }

    public void addMarker(final MarkerOptions options) {
        addMarker(options, null);
    }

    public void addMarker(final MarkerOptions options, final Object tag) {
        execute(new Runnable() {
            @Override
            public void run() {
                Marker marker = getMap().addMarker(options);
                if (tag != null) {
                    addTag(marker, tag);
                }
            }
        });
    }

    public void addGroundOverlay(final GroundOverlayOptions options) {
        execute(new Runnable() {
            @Override
            public void run() {
                getMap().addGroundOverlay(options);
            }
        });
    }

    public void addTileOverlay(final TileOverlayOptions options) {
        execute(new Runnable() {
            @Override
            public void run() {
                getMap().addTileOverlay(options);
            }
        });
    }

    /*
     *  UI SETTINGS
     */
    public void setMapToolbarEnabled(final boolean enabled) {
        execute(new Runnable() {
            @Override
            public void run() {
                getMap().getUiSettings().setMapToolbarEnabled(enabled);
            }
        });
    }

    public void setPadding(final int left, final int top, final int right, final int bottom) {
        execute(new Runnable() {
            @Override
            public void run() {
                getMap().setPadding(left, top, right, bottom);
            }
        });
    }

    public void setZoomControlsEnabled(final boolean enabled) {
        execute(new Runnable() {
            @Override
            public void run() {
                getMap().getUiSettings().setZoomControlsEnabled(enabled);
            }
        });
    }

    public void setCompassEnabled(final boolean enabled) {
        execute(new Runnable() {
            @Override
            public void run() {
                getMap().getUiSettings().setCompassEnabled(enabled);
            }
        });
    }

    public void setMyLocationButtonEnabled(final boolean enabled) {
        execute(new Runnable() {
            @Override
            public void run() {
                getMap().getUiSettings().setMyLocationButtonEnabled(enabled);
            }
        });
    }

    public void setIndoorLevelPickerEnabled(final boolean enabled) {
        execute(new Runnable() {
            @Override
            public void run() {
                getMap().getUiSettings().setIndoorLevelPickerEnabled(enabled);
            }
        });
    }

    public void setScrollGesturesEnabled(final boolean enabled) {
        execute(new Runnable() {
            @Override
            public void run() {
                getMap().getUiSettings().setScrollGesturesEnabled(enabled);
            }
        });
    }

    public void setZoomGesturesEnabled(final boolean enabled) {
        execute(new Runnable() {
            @Override
            public void run() {
                getMap().getUiSettings().setZoomGesturesEnabled(enabled);
            }
        });
    }

    public void setTiltGesturesEnabled(final boolean enabled) {
        execute(new Runnable() {
            @Override
            public void run() {
                getMap().getUiSettings().setTiltGesturesEnabled(enabled);
            }
        });
    }

    public void setRotateGesturesEnabled(final boolean enabled) {
        execute(new Runnable() {
            @Override
            public void run() {
                getMap().getUiSettings().setRotateGesturesEnabled(enabled);
            }
        });
    }

    public void setAllGesturesEnabled(final boolean enabled) {
        execute(new Runnable() {
            @Override
            public void run() {
                getMap().getUiSettings().setAllGesturesEnabled(enabled);
            }
        });
    }

    public void setInfoWindowAdapter(final GoogleMap.InfoWindowAdapter adapter) {
        execute(new Runnable() {
            @Override
            public void run() {
                getMap().setInfoWindowAdapter(adapter);
            }
        });
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {

        map = googleMap;

        setUpMap();

    }

    public void setUpMap() {

        map.setMapType(GoogleMap.MAP_TYPE_HYBRID);
        if (ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            // TODO: Consider calling
            //    ActivityCompat#requestPermissions
            // here to request the missing permissions, and then overriding
            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
            //                                          int[] grantResults)
            // to handle the case where the user grants the permission. See the documentation
            // for ActivityCompat#requestPermissions for more details.
            return;
        }
        map.setMyLocationEnabled(true);
    }

    @Override
    public void onConnected(Bundle bundle) {

        mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(1000);
        mLocationRequest.setFastestInterval(1000);
        mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);

        //mLocationRequest.setSmallestDisplacement(0.1F);

        if (ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            // TODO: Consider calling
            //    ActivityCompat#requestPermissions
            // here to request the missing permissions, and then overriding
            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
            //                                          int[] grantResults)
            // to handle the case where the user grants the permission. See the documentation
            // for ActivityCompat#requestPermissions for more details.
            return;
        }
        LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
    }

    @Override
    public void onConnectionSuspended(int i) {

    }

    @Override
    public void onLocationChanged(Location location) {
        mLastLocation = location;

        //remove previous current location Marker
        if (marker != null){
            marker.remove();
        }

        double dLatitude = mLastLocation.getLatitude();
        double dLongitude = mLastLocation.getLongitude();
        marker = map.addMarker(new MarkerOptions().position(new LatLng(dLatitude, dLongitude))
                .title("My Location").icon(BitmapDescriptorFactory
                        .defaultMarker(BitmapDescriptorFactory.HUE_RED)));
        map.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(dLatitude, dLongitude), 8));

    }

    @Override
    public void onPause() {
        super.onPause();
        if (mGoogleApiClient != null) {
            LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
        }
    }

    protected synchronized void buildGoogleApiClient() {
        mGoogleApiClient = new GoogleApiClient.Builder(getContext())
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();
    }

    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {

    }

}

Is there a zoom feature available? Also my api allows me to access zip code of user. Can I use that instead? I require user to be shown his nearby locations.

解决方案

This is similar to my other answer here, however, this is different due to the fact that you are extending the MapFragment and have your custom behavior implemented inside the Fragment.

Here is an example Fragment that extends SupportMapFragment, on launch it will get the user's current location, place a Marker, and zoom in:

public class MapFragment extends SupportMapFragment
        implements OnMapReadyCallback,
        GoogleApiClient.ConnectionCallbacks,
        GoogleApiClient.OnConnectionFailedListener,
        LocationListener {

    GoogleMap mGoogleMap;
    SupportMapFragment mapFrag;
    LocationRequest mLocationRequest;
    GoogleApiClient mGoogleApiClient;
    Location mLastLocation;
    Marker mCurrLocationMarker;

    @Override
    public void onResume() {
        super.onResume();

        setUpMapIfNeeded();
    }

    private void setUpMapIfNeeded() {

        if (mGoogleMap == null) {
            getMapAsync(this);
        }
    }
    @Override
    public void onPause() {
        super.onPause();

        //stop location updates when Activity is no longer active
        if (mGoogleApiClient != null) {
            LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
        }
    }

    @Override
    public void onMapReady(GoogleMap googleMap)
    {
        mGoogleMap=googleMap;
        mGoogleMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);

        //Initialize Google Play Services
        if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (ContextCompat.checkSelfPermission(getActivity(),
                    Manifest.permission.ACCESS_FINE_LOCATION)
                    == PackageManager.PERMISSION_GRANTED) {
                //Location Permission already granted
                buildGoogleApiClient();
                mGoogleMap.setMyLocationEnabled(true);
            } else {
                //Request Location Permission
                checkLocationPermission();
            }
        }
        else {
            buildGoogleApiClient();
            mGoogleMap.setMyLocationEnabled(true);
        }
    }

    protected synchronized void buildGoogleApiClient() {
        mGoogleApiClient = new GoogleApiClient.Builder(getActivity())
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();
        mGoogleApiClient.connect();
    }

    @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(getActivity(),
                Manifest.permission.ACCESS_FINE_LOCATION)
                == PackageManager.PERMISSION_GRANTED) {
            LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
        }
    }

    @Override
    public void onConnectionSuspended(int i) {}

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {}

    @Override
    public void onLocationChanged(Location location)
    {
        mLastLocation = location;
        if (mCurrLocationMarker != null) {
            mCurrLocationMarker.remove();
        }

        //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 = mGoogleMap.addMarker(markerOptions);

        //move map camera
        mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng,11));

    }

    public static final int MY_PERMISSIONS_REQUEST_LOCATION = 99;
    private void checkLocationPermission() {
        if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION)
                != PackageManager.PERMISSION_GRANTED) {

            // Should we show an explanation?
            if (ActivityCompat.shouldShowRequestPermissionRationale(getActivity(),
                    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.
                new AlertDialog.Builder(getActivity())
                        .setTitle("Location Permission Needed")
                        .setMessage("This app needs the Location permission, please accept to use location functionality")
                        .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialogInterface, int i) {
                                //Prompt the user once explanation has been shown
                                ActivityCompat.requestPermissions(getActivity(),
                                        new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                                        MY_PERMISSIONS_REQUEST_LOCATION );
                            }
                        })
                        .create()
                        .show();


            } else {
                // No explanation needed, we can request the permission.
                ActivityCompat.requestPermissions(getActivity(),
                        new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                        MY_PERMISSIONS_REQUEST_LOCATION );
            }
        }
    }

    @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, yay! Do the
                    // location-related task you need to do.
                    if (ContextCompat.checkSelfPermission(getActivity(),
                            Manifest.permission.ACCESS_FINE_LOCATION)
                            == PackageManager.PERMISSION_GRANTED) {

                        if (mGoogleApiClient == null) {
                            buildGoogleApiClient();
                        }
                        mGoogleMap.setMyLocationEnabled(true);
                    }

                } else {

                    // permission denied, boo! Disable the
                    // functionality that depends on this permission.
                    Toast.makeText(getActivity(), "permission denied", Toast.LENGTH_LONG).show();
                }
                return;
            }

            // other 'case' lines to check for other
            // permissions this app might request
        }
    }

}

Since the Location permission request needs to go through the Activity, you will need to route the result from the Activity to the Fragment's onRequestPermissionsResult() method:

public class MainActivity extends AppCompatActivity {

    MapFragment mapFragment;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        mapFragment = new MapFragment();

        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
        transaction.add(R.id.mapframe, mapFragment);
        transaction.commit();
    }

    @Override
    public void onRequestPermissionsResult(int requestCode,
                                           String permissions[], int[] grantResults) {
        if (requestCode == MapFragment.MY_PERMISSIONS_REQUEST_LOCATION){
            mapFragment.onRequestPermissionsResult(requestCode, permissions, grantResults);
        }
        else {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }

}

The layout just contains a FrameLayout where the MapFragment goes.

activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:context="com.danielnugent.mapapplication.MainActivity">

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/AppTheme.PopupOverlay" />

    </android.support.design.widget.AppBarLayout>

    <FrameLayout
        android:id="@+id/mapframe"
        android:layout_marginTop="?attr/actionBarSize"
        android:layout_height="match_parent"
        android:layout_width="match_parent" />

</android.support.design.widget.CoordinatorLayout>

Result

First prompt for the Location permission:

Once the Location permission is granted, show the current location with a Marker:

If the user ever denies or revokes the Location permission, this will be shown on app launch:

First, the explanation:

Then, the Location permission request:

这篇关于显示Google Map Fragment中的当前位置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆