gpt4 book ai didi

android - 在后台获取 GoogleMap 快照

转载 作者:太空宇宙 更新时间:2023-11-03 10:34:49 32 4
gpt4 key购买 nike

我试图在后台获取 GoogleMap(来自 MapView)的快照,通过回调返回它并在 ImageView 中显示它。在这样做的同时,我试图让快照部分尽可能独立于布局(因此,尽量避免将 MapView 添加到布局中)。我尝试过以编程方式创建具有给定大小的 MapView,在其上添加一些路径和引脚,获取快照并返回它(全部使用 RxJava 订阅)但我收到以下错误并且应用程序正在关闭甚至没有“应用停止工作”对话框。

FATAL EXCEPTION: androidmapsapi-Snapshot Process:
com.package.name.debug, PID: 2159
java.lang.IllegalArgumentException: width and height must be > 0
at android.graphics.Bitmap.createBitmap(Bitmap.java:1013)
at android.graphics.Bitmap.createBitmap(Bitmap.java:980)
at android.graphics.Bitmap.createBitmap(Bitmap.java:930)
at android.graphics.Bitmap.createBitmap(Bitmap.java:891)
at com.google.maps.api.android.lib6.impl.ec.b(:com.google.android.gms.DynamiteModulesB@11975940:4)
at com.google.maps.api.android.lib6.impl.bf.run(:com.google.android.gms.DynamiteModulesB@11975940:4)
at java.lang.Thread.run(Thread.java:764)

获取快照的代码如下

fun bitmapFor(mapData: MapData, specs: Specs): Single<Bitmap?> {
val mapView = MapView(context)
mapView.layoutParams = ViewGroup.LayoutParams(specs.mapWidth, specs.mapHeight)

return mapView.getMap()
.subscribeOn(AndroidSchedulers.mainThread())
.map { googleMap ->
setupMap(googleMap, mapData) // Adds paths and pins
googleMap
}
.flatMap { googleMap ->
googleMap.snapshot(mapData)
}
}

private fun MapView.getMap(): Single<GoogleMap> {
return Single.create { subscriber ->

val handler = Handler(Looper.getMainLooper())
handler.post {
onCreate(null)
onStart()
onResume()

getMapAsync { googleMap ->
subscriber.onSuccess(googleMap)
}
}
}
}

private fun GoogleMap.snapshot(mapData: MapData): Single<Bitmap> {
return Single.create { subscriber ->
snapshot { bitmap ->
saveMap(mapData.hashCode().toString(), bitmap)
subscriber.onSuccess(bitmap)
}
}
}

在 UI 类中,我正在做

viewModel.mapProvider
.bitmapFor(map, viewModel.mapData, Specs(map.measuredWidth, map.measuredHeight))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(this::onMap, this::onError) // onMap set's the image bitmap

最佳答案

请查看更新!

似乎无法在不可见的 MapView 背景上获取 Google map 快照,因为本地图不可见时,它甚至没有开始加载。您可以为不可见的 MapVew 设置正确的大小(例如,基于 this 文章),但它似乎是带有“Google” Logo 的空黑条。可能最简单的解决方法 - 仍然显示 MapView,但禁用其上的控件和手势:

`public void onMapReady(GoogleMap googleMap) {
mGoogleMap = googleMap;
mGoogleMap.getUiSettings().setAllGesturesEnabled(false);
...
}`

或通过 Static Map API 下载 map 图像,并在下载的位图上本地绘制您需要的任何内容。

更新:

通过将其设置为 Lite Mode,可以在不可见的 MapView 背景上获取 Google map 快照。关于创作:

...
GoogleMapOptions options = new GoogleMapOptions()
.compassEnabled(false)
.mapToolbarEnabled(false)
.camera(CameraPosition.fromLatLngZoom(KYIV,15))
.liteMode(true);
mMapView = new MapView(this, options);
...

并且有必要通过measure()layout()onMapReady()中确定MapView的大小> 启动 map 图像加载的调用 - 在 map 图像加载后,可以在 onMapLoaded() 回调中获取它:

mMapView.setDrawingCacheEnabled(true);
mMapView.measure(View.MeasureSpec.makeMeasureSpec(mMapWidth, View.MeasureSpec.EXACTLY),
View.MeasureSpec.makeMeasureSpec(mMapHeight, View.MeasureSpec.EXACTLY));
mMapView.layout(0, 0, mMapWidth, mMapHeight);
mMapView.buildDrawingCache(true);
Bitmap b = Bitmap.createBitmap(mMapView.getDrawingCache()); // <- that is bitmap with map image
mMapView.setDrawingCacheEnabled(false);

必须在 getMapAsyhc() 之前调用 MapView 对象上的 onCreate()otherwise no map will appear .

完整源代码:

public class MainActivity extends AppCompatActivity {

private static final String MAP_VIEW_BUNDLE_KEY = "MapViewBundleKey";
static final LatLng KYIV = new LatLng(50.450311, 30.523730);

private ImageView mImageView;

private MapView mMapView;
// dimensions of map image
private int mMapWidth = 600;
private int mMapHeight = 800;

@Override
protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

mImageView = (ImageView) findViewById(R.id.image_view);

Bundle mapViewBundle = null;
if (savedInstanceState != null) {
mapViewBundle = savedInstanceState.getBundle(MAP_VIEW_BUNDLE_KEY);
}

GoogleMapOptions options = new GoogleMapOptions()
.compassEnabled(false)
.mapToolbarEnabled(false)
.camera(CameraPosition.fromLatLngZoom(KYIV,15))
.liteMode(true);
mMapView = new MapView(this, options);
mMapView.onCreate(mapViewBundle);

mMapView.getMapAsync(new OnMapReadyCallback() {
@Override
public void onMapReady(GoogleMap googleMap) {

// form your card (add markers, path etc.) here:
googleMap.addMarker(new MarkerOptions()
.position(KYIV)
.title("Kyiv"));

// set map size in pixels and initiate image loading
mMapView.measure(View.MeasureSpec.makeMeasureSpec(mMapWidth, View.MeasureSpec.EXACTLY),
View.MeasureSpec.makeMeasureSpec(mMapHeight, View.MeasureSpec.EXACTLY));
mMapView.layout(0, 0, mMapWidth, mMapHeight);

googleMap.setOnMapLoadedCallback(new GoogleMap.OnMapLoadedCallback() {
@Override
public void onMapLoaded() {
mMapView.setDrawingCacheEnabled(true);
mMapView.measure(View.MeasureSpec.makeMeasureSpec(mMapWidth, View.MeasureSpec.EXACTLY),
View.MeasureSpec.makeMeasureSpec(mMapHeight, View.MeasureSpec.EXACTLY));
mMapView.layout(0, 0, mMapWidth, mMapHeight);
mMapView.buildDrawingCache(true);
Bitmap b = Bitmap.createBitmap(mMapView.getDrawingCache());
mMapView.setDrawingCacheEnabled(false);
mImageView.setImageBitmap(b);

}
});

}
});
}

@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);

Bundle mapViewBundle = outState.getBundle(MAP_VIEW_BUNDLE_KEY);
if (mapViewBundle == null) {
mapViewBundle = new Bundle();
outState.putBundle(MAP_VIEW_BUNDLE_KEY, mapViewBundle);
}
}
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="{PACKAGE_NAME}.MainActivity">

<ImageView
android:id="@+id/image_view"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>

</RelativeLayout>

在 map 上获取带有标记的屏幕截图:

MapView screenshot example

如果您希望在精简模式 map 上显示“我的位置”点并使用默认位置源,您需要调用 onResume()onPause() :

...
@Override
protected void onResume() {
super.onResume();
if (mMapView != null) {
mMapView.onResume();
}
}

@Override
protected void onPause() {
if (mMapView != null) {
mMapView.onPause();
}
super.onPause();
}
...

因为位置源只会更新between these calls .

关于android - 在后台获取 GoogleMap 快照,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48621401/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com