我有一个使用android-maps-utils和滑动标记图标的应用程序.
我收到了使用Firebase崩溃报告的错误报告,我无法在源代码中跟踪,因为它gms.maps.model.Marker.setIcon
是私有的,所以我要求帮助解决这个问题.
问题的以下部分分为:
用户正在做什么
他在地图中放大和缩小(Fragment
使用com.google.android.gms.maps.SupportMapFragment
)
火灾基地崩溃向我报告了什么
异常java.lang.IllegalArgumentException:非托管描述符
com.google.maps.api.android.lib6.common.kb(:com.google.android.gms.DynamiteModulesB:162)
com.google.maps.api.android.lib6. impl.oc(:com.google.android.gms.DynamiteModulesB:75)
com.google.maps.api.android.lib6.impl.db.a(:com.google.android.gms.DynamiteModulesB:334)
com. google.android.gms.maps.model.internal.q.onTransact(:com.google.android.gms.DynamiteModulesB:204)
android.os.Binder.transact(Binder.java:387)
com.google.android.gms .maps.model.internal.zzf $ zza $ zza.zzL()com.google.android.gms.maps.model.Marker.setIcon()
co.com.spyspot.ui.content.sucursal.SucursalRender $ CustomSimpleTarget.onResourceReady (SucursalRender.java:156)co.com.spyspot.ui.content.sucursal.SucursalRender
$ CustomSimpleTarget.onResourceReady(SucursalRender.java:130)
com.bumptech.glide.request.GenericRequest.onResourceReady(GenericRequest.java:525)
com .bumptech.glide.request.GenericRequest.onResourceReady(GenericRequest.java:507)
com.bumptech.g lide.load.engine.EngineJob.handleResultOnMainThread(EngineJob.java:158)
com.bumptech.glide.load.engine.EngineJob.access $ 100(EngineJob.java:22)
com.bumptech.glide.load.engine.EngineJob $ MainThreadCallback .handleMessage(EngineJob.java:202)
android.os.Handler.dispatchMessage(Handler.java:98)
android.os.Looper.loop(Looper.java:148)
android.app.ActivityThread.main(ActivityThread.java:5443 )
java.lang.reflect.Method.invoke(Method.java)
com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:728)
com.android.internal.os.ZygoteInit.main(ZygoteInit.java) :618)
和:
一些项目配置
SucursalRender extends DefaultClusterRenderer<Sucursal>
)Glide.with(context).load(id).fitCenter().placeholder(R.drawable.ic_no_image).into(simpleTarget);
这simpleTarget
是我处理Glide下载/缓存的图像的地方.我发布了所有代码,simpleTarget
因为崩溃是从那里开始的:
private class CustomSimpleTarget extends …
Run Code Online (Sandbox Code Playgroud) 嗨我正在发出服务器请求,当我收到来自服务器的请求时,我正在Ui Thread上执行一个ClusterManager.addItem(),但这些项目不会在地图中绘制,只有当我进行缩放更新(+, - )时正在显示.此外,我尝试调试渲染器,但是直到我更新地图中的缩放才调用onBeforeClusterRendered/onBeforeClusterItemRendered.有关如何刷新map/clusterManager/markers的任何想法?
MarkerManager markerManager = new MarkerManager(map);
clusterManager = new ClusterManager<TweetClusterItem>(getActivity(), map, markerManager);
clusterManager.setRenderer(new TweetClusterRenderer(getActivity(), map, clusterManager, defaultMarker));
clusterManager.setOnClusterClickListener(this);
clusterManager.setOnClusterInfoWindowClickListener(this);
clusterManager.setOnClusterItemClickListener(this);
clusterManager.setOnClusterItemInfoWindowClickListener(this);
UiSettings uiSettings = map.getUiSettings();
uiSettings.setZoomControlsEnabled(true);
uiSettings.setMyLocationButtonEnabled(false);
map.setOnCameraChangeListener(clusterManager);
map.setOnMarkerClickListener(clusterManager);
map.setOnInfoWindowClickListener(clusterManager);
map.setOnMapClickListener(this);
Run Code Online (Sandbox Code Playgroud) 为了获得用户当前位置,我使用过LocationManager:
LocationManager locationManager = (LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE);
if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
} else if (locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
}
Run Code Online (Sandbox Code Playgroud)
它易于阅读且代码非常简单.
但我注意到Google最近在Google Play服务中发布了新客户端API模型并建议使用FusedLocationProviderApi,它看起来更复杂,它是异步的,它需要处理回调等.
在LocationManager上使用FusedLocationProviderApi有什么好处吗?
android android-location google-play-services android-maps-utils
当我使用集群管理器以编程方式在地图上添加新标记时,它不会反映更改,直到我更新放大和缩小.
我已经看到很多关于堆栈溢出的问题,但这对我不起作用,
所以请告诉我如何在不清除地图的情况下更新地图.
码:
for (int i = 0; i < name.length; i++)
{
Person_marker person_marker = new Person_marker(createRandLocation(latLng),
name[i], getAddress(latLng), typedArray.getResourceId(i, -1), time[i], acuracy[i]);
person_markerList.add(person_marker);
}
clusterManager.clearItems(); clusterManager.addItems(person_markerList);
Run Code Online (Sandbox Code Playgroud) 我使用的是地图上的机器人聚集效用和succesffuly实现与mClusterManager.setOnClusterItemClickListener()一个onclick侦听由聚类库处理的所有标记.
因为我还想要一些标记总是非聚集的,我也添加一些标记而不使用mClusterManager但是直接使用地图的mMap.addMarker(),这样我确信它们永远不会聚集在地图上.
我的问题是我无法拦截那些标记上的点击(总是非集群的标记),因为我已经使用了mMap.setOnMarkerClickListener(mClusterManager)来处理点击的集群标记.
有没有办法收听点击的聚类标记和聚类库未处理的点击标记?
或者有没有办法指定集群管理器永远不会聚集一些标记?在这种情况下,我不必处理那些不同的点击侦听器,因为所有标记都将使用群集实用程序显示.
谢谢
在我的Android项目中,我使用android-maps-utils库将聚类应用于地图视图上的一堆标记.只要点击一个标记,我就会得到通知,onClusterItemClick
所以我可以做一些动作.
public interface OnClusterItemClickListener<T extends ClusterItem> {
public boolean onClusterItemClick(T item);
}
Run Code Online (Sandbox Code Playgroud)
现在我想让用户知道点击了哪个标记.简单的视觉反馈是改变标记图标的(颜色).可以通过MarkerOptions
可在以下位置访问的对象设置图标onBeforeClusterItemRendered(T item, MarkerOptions markerOptions)
:
markerOptions.icon(
BitmapDescriptorFactory.defaultMarker(
BitmapDescriptorFactory.HUE_YELLOW));
Run Code Online (Sandbox Code Playgroud)
如果我可以访问Marker
对象本身,例如onMarkerClick (Marker marker)
我可以通过更改图标setIcon
.
如何更改点击的标记图标?
我已经实现了Google Maps Clustering的代码
这是我活动中的代码
private void setUpClusterer() {
mClusterManager = new ClusterManager<StoreItem>(this, mMap);
mMap.setOnCameraChangeListener(mClusterManager);
mMap.setOnMarkerClickListener(mClusterManager);
}
public void addItems(List<Store> stores) {
for (Store store : stores) {
mClusterManager.addItem(new StoreItem(store.getImage(), store.getLocation().getLatitude(), store.getLocation().getLongitude()));
}
}
private void removeAllItems() {
mClusterManager.clearItems();
}
Run Code Online (Sandbox Code Playgroud)
这是StoreItem类
public class StoreItem implements ClusterItem {
private String url;
private final LatLng mPosition;
public StoreItem(String url, double lat, double lng) {
this.url = url;
mPosition = new LatLng(lat, lng);
}
@Override
public LatLng getPosition() {
return mPosition;
} …
Run Code Online (Sandbox Code Playgroud) 我的 Android 应用程序中有一个谷歌地图。它充满了标记,它聚集了标记......简而言之,这是一张完全可用的地图。
我想做的事情很简单。当用户点击 clusterItem 时,我想将图标更改为选定的图标。(简单地说,相同的标记但颜色不同)。
我如何在屏幕上使用大量标记,每次单击标记时都不可能清理地图并添加标记。
所以:
mClusterManager.setOnClusterItemClickListener(new ClusterManager.OnClusterItemClickListener<MyItem>() {
@Override
public boolean onClusterItemClick(MyItem myItem) {
if (oldItemSelected != null) {
mClusterManager.removeItem(oldItemSelected);
oldItemSelected.setItemAsNotSelected();
mClusterManager.addItem(oldItemSelected);
}
mClusterManager.removeItem(myItem);
myItem.setItemAsSelected();
mClusterManager.addItem(myItem);
mClusterManager.cluster();
oldItemSelected = myItem;
return true;
}
});
Run Code Online (Sandbox Code Playgroud)
这个想法是从地图中删除单击的项目,将其设置为“选定”,添加新项目并使用 .cluster 方法刷新地图。
会发生什么:该项目没有改变,有时该项目是“重复的”并且所选项目位于“正常”项目的后面。
这就是我设置集群管理器的方式:
mClusterManager = new ClusterManager<MyItem>(this, map);
mClusterManager.setRenderer(new MyItemRenderer());
mClusterManager.setAlgorithm(new GridBasedAlgorithm<MyItem>());
map.setOnMarkerClickListener(mClusterManager);
Run Code Online (Sandbox Code Playgroud)
这是项目渲染器:
private class MyItemRenderer extends DefaultClusterRenderer<MyItem> {
public MyItemRenderer() {
super(getApplicationContext(), map, mClusterManager);
}
@Override
protected void onBeforeClusterItemRendered(MyItem myItem, MarkerOptions markerOptions) {
markerOptions.title(myItem.getName());
markerOptions.snippet(myItem.getAddress());
markerOptions.icon(BitmapDescriptorFactory.fromResource(myItem.getIcon()));
}
@Override
protected …
Run Code Online (Sandbox Code Playgroud) 在尝试实现使用时ClusterManager
,我注意到它已getMap().setOnCameraChangeListener(clusterManager)
被弃用.看一下Github上的android-maps-utils示例,我注意到了getMap().setOnCameraIdleListener(mClusterManager);
当我尝试做同样的事情时,我得到一个错误,因为默认ClusterManager
类没有实现GoogleMap.OnCameraIdleListener
.
然而,在我的gradle文件中,我使用的是最新的maps-util库:
dependencies {
compile 'com.google.maps.android:android-maps-utils:0.4.3'
}
Run Code Online (Sandbox Code Playgroud)
我怎样才能访问最新的ClusterManager
课程?谢谢
我的应用程序有1.5万个标记,通过标记聚类显示.
实际上它使用默认标记工作正常,但我想使用矢量位图和渲染标记与文本(加油站的价格),如下所示:
在完成渲染标记之前,会发生以下异常:"无法分配dup blob fd."
我认为这是某种内存溢出,但我不知道如何解决它.有没有人知道如何解决这个问题或有另一个如何管理这么多标记的建议?
注意:我已经在使用标记聚类.
注意:仅在某些Motorola和LG设备上出现此问题.在大多数设备工作正常.一些代码:
public class OwnRendring extends DefaultClusterRenderer<MyItem> {
public OwnRendring(Context context, GoogleMap map, ClusterManager<MyItem> clusterManager) {
super(context, map, clusterManager);
}
protected void onBeforeClusterItemRendered(MyItem item, MarkerOptions markerOptions) {
markerOptions.snippet(item.getSnippet());
markerOptions.title(item.getTitle());
markerOptions.anchor(0.33f, 1f);
markerOptions.infoWindowAnchor(0.33f,0f);
int cor;
if (item.getPublico()) {
cor=cfgCorPostoPublico;
} else {
cor=cfgCorPostoPrivado;
}
String preço = item.getTitle().substring(item.getTitle().length() - 5);
if (Objects.equals(preço, "0,000")) { preço=""; }
Bitmap bitmap = createStoreMarker(preço, cor);
markerOptions.icon(BitmapDescriptorFactory.fromBitmap(bitmap));
super.onBeforeClusterItemRendered(item, markerOptions);
}
protected boolean shouldRenderAsCluster(Cluster cluster) {
// if markers < cfgClusterMin …
Run Code Online (Sandbox Code Playgroud)