- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我目前正在处理一个包含 Google map 的 fragment 。一旦用户访问该 fragment ,他的 map 应该缩放并关注他的位置。然而,它显示的是世界地图而不是附近的位置(靠近用户):
@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) {
}
}
有缩放功能吗?我的 api 也允许我访问用户的邮政编码。我可以用那个代替吗?我要求向用户显示他附近的位置。
最佳答案
这类似于我的 other answer here ,但是,这是不同的,因为您正在扩展 MapFragment 并在 Fragment 中实现自定义行为。
这是一个扩展 SupportMapFragment 的示例 fragment ,在启动时它将获取用户的当前位置、放置标记并放大:
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
}
}
}
由于 Location 权限请求需要通过 Activity,因此您需要将 Activity 的结果路由到 Fragment 的 onRequestPermissionsResult()
方法:
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);
}
}
}
布局仅包含 MapFragment 所在的 FrameLayout。
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>
结果
首先提示位置权限:
授予位置权限后,使用标记显示当前位置:
如果用户曾经拒绝或撤销位置权限,这将在应用启动时显示:
首先说明:
然后,位置权限请求:
关于android - 在谷歌地图 fragment 中显示当前位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41753706/
我需要将文本放在 中在一个 Div 中,在另一个 Div 中,在另一个 Div 中。所以这是它的样子: #document Change PIN
奇怪的事情发生了。 我有一个基本的 html 代码。 html,头部, body 。(因为我收到了一些反对票,这里是完整的代码) 这是我的CSS: html { backgroun
我正在尝试将 Assets 中的一组图像加载到 UICollectionview 中存在的 ImageView 中,但每当我运行应用程序时它都会显示错误。而且也没有显示图像。 我在ViewDidLoa
我需要根据带参数的 perl 脚本的输出更改一些环境变量。在 tcsh 中,我可以使用别名命令来评估 perl 脚本的输出。 tcsh: alias setsdk 'eval `/localhome/
我使用 Windows 身份验证创建了一个新的 Blazor(服务器端)应用程序,并使用 IIS Express 运行它。它将显示一条消息“Hello Domain\User!”来自右上方的以下 Ra
这是我的方法 void login(Event event);我想知道 Kotlin 中应该如何 最佳答案 在 Kotlin 中通配符运算符是 * 。它指示编译器它是未知的,但一旦知道,就不会有其他类
看下面的代码 for story in book if story.title.length < 140 - var story
我正在尝试用 C 语言学习字符串处理。我写了一个程序,它存储了一些音乐轨道,并帮助用户检查他/她想到的歌曲是否存在于存储的轨道中。这是通过要求用户输入一串字符来完成的。然后程序使用 strstr()
我正在学习 sscanf 并遇到如下格式字符串: sscanf("%[^:]:%[^*=]%*[*=]%n",a,b,&c); 我理解 %[^:] 部分意味着扫描直到遇到 ':' 并将其分配给 a。:
def char_check(x,y): if (str(x) in y or x.find(y) > -1) or (str(y) in x or y.find(x) > -1):
我有一种情况,我想将文本文件中的现有行包含到一个新 block 中。 line 1 line 2 line in block line 3 line 4 应该变成 line 1 line 2 line
我有一个新项目,我正在尝试设置 Django 调试工具栏。首先,我尝试了快速设置,它只涉及将 'debug_toolbar' 添加到我的已安装应用程序列表中。有了这个,当我转到我的根 URL 时,调试
在 Matlab 中,如果我有一个函数 f,例如签名是 f(a,b,c),我可以创建一个只有一个变量 b 的函数,它将使用固定的 a=a1 和 c=c1 调用 f: g = @(b) f(a1, b,
我不明白为什么 ForEach 中的元素之间有多余的垂直间距在 VStack 里面在 ScrollView 里面使用 GeometryReader 时渲染自定义水平分隔线。 Scrol
我想知道,是否有关于何时使用 session 和 cookie 的指南或最佳实践? 什么应该和什么不应该存储在其中?谢谢! 最佳答案 这些文档很好地了解了 session cookie 的安全问题以及
我在 scipy/numpy 中有一个 Nx3 矩阵,我想用它制作一个 3 维条形图,其中 X 轴和 Y 轴由矩阵的第一列和第二列的值、高度确定每个条形的 是矩阵中的第三列,条形的数量由 N 确定。
假设我用两种不同的方式初始化信号量 sem_init(&randomsem,0,1) sem_init(&randomsem,0,0) 现在, sem_wait(&randomsem) 在这两种情况下
我怀疑该值如何存储在“WORD”中,因为 PStr 包含实际输出。? 既然Pstr中存储的是小写到大写的字母,那么在printf中如何将其给出为“WORD”。有人可以吗?解释一下? #include
我有一个 3x3 数组: var my_array = [[0,1,2], [3,4,5], [6,7,8]]; 并想获得它的第一个 2
我意识到您可以使用如下方式轻松检查焦点: var hasFocus = true; $(window).blur(function(){ hasFocus = false; }); $(win
我是一名优秀的程序员,十分优秀!