【问题标题】:GoogleMap snapshot method returns white imageGoogleMap 快照方法返回白色图像
【发布时间】:2014-03-16 19:23:15
【问题描述】:

我正在尝试使用提到的 API here 获取 Google Maps V2 地图的屏幕截图,但这似乎总是返回底部带有 Google 徽标的白色图像。如果不是因为徽标,我会确定这根本不起作用,但徽标意味着正在发生某些事情并且地图没有显示。这大致就是我正在做的事情:

mv.setVisibility(View.VISIBLE);
mv.getMap().snapshot(new GoogleMap.SnapshotReadyCallback() {
    public void onSnapshotReady(Bitmap snapshot) {
        synchronized(finished) {
            finished[0] = snapshot;
            finished.notify();
        }
    }
});

我尝试了多种不同的方法,包括将图像绘制到不同的图像以及其他各种尝试。

唯一的主要区别是我使用的是 MapView 而不是 MapFragment,由于一些技术问题,我无法在此处切换到使用片段。

【问题讨论】:

  • 您必须等待地图通过 OnMapLoadedCallback 加载,然后请求快照。

标签: android google-maps google-maps-android-api-2 codenameone


【解决方案1】:

要拍摄快照,您需要等待地图加载然后拍摄快照。

详情: 实现 SnapshotReadyCallback 和 OnMapLoadedCallback。

import com.google.android.gms.maps.GoogleMap.SnapshotReadyCallback;
import com.google.android.gms.maps.GoogleMap.OnMapLoadedCallback;

public class KmlReader extends ActionBarActivity implements
     SnapshotReadyCallback,
    OnMapLoadedCallback {

...

 if (mMap == null) {
// Try to obtain the map from the SupportMapFragment.
// mMap = mMapFragment.getMap();
// // Check if we were successful in obtaining the map.

// Try to obtain the map from the SupportMapFragment.
mMap = ((SupportMapFragment) getSupportFragmentManager()
        .findFragmentById(R.id.map)).getMap();
// use the settings maptype

// Check if we were successful in obtaining the map.
if (mMap != null) {

mMap.setOnMapLoadedCallback(this);

...

@Override
public void onMapLoaded() {
   if (mMap != null) {
        mMap.snapshot(this);
   }
}

当它触发时,你有一个真实的位图。

@Override
public void onSnapshotReady(Bitmap bm) {
    if (CheckStorage.isExternalStorageWritable()) {
        int newHeight = 96;
        int newWidth = 96;

        int width = bm.getWidth();

        int height = bm.getHeight();

        float scaleWidth = ((float) newWidth) / width;

        float scaleHeight = ((float) newHeight) / height;

        // create a matrix for the manipulation

        Matrix matrix = new Matrix();

        // resize the bit map

        matrix.postScale(scaleWidth, scaleHeight);

        // recreate the new Bitmap

        Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height,
                matrix, false);

【讨论】:

  • 谢谢,当我尝试拍摄时,地图正在显示。这是否意味着它已加载?
  • 我刚刚尝试过,得到了几乎相同的结果,但它仍然不起作用。感谢您的努力。
  • 对不起,它不适合你。它对我有用,我能够通过在 onMapLoaded 方法触发之前拍摄快照来复制您的问题。
  • 虽然这不能解决我的问题,但我接受了它作为答案,因为对于大多数人来说这将是正确的答案。为我们解决的是一些我不太了解且与 Android 完全无关的内部逻辑。
【解决方案2】:

这对我有用。希望对你有帮助:

SnapshotReadyCallback callback = new SnapshotReadyCallback() {
                Bitmap bitmap;

                @Override
                public void onSnapshotReady(Bitmap snapshot) {
                    // TODO Auto-generated method stub
                    bitmap = snapshot;
                    try {
                        String mPath = Environment.getExternalStorageDirectory().toString();
                        FileOutputStream out = new FileOutputStream(mPath + "/ "+ nom + ".png");
                        bitmap.compress(Bitmap.CompressFormat.PNG, 90, out);
                        Toast.makeText(getActivity(), "Capture OK", Toast.LENGTH_LONG).show();
                    } catch (Exception e) {
                        e.printStackTrace();
                        Toast.makeText(getActivity(), "Capture NOT OK", Toast.LENGTH_LONG).show();
                    }
                }
            };
            map.snapshot(callback);
            return true;

【讨论】:

  • 谢谢,但我认为这与我的代码没有太大区别。
【解决方案3】:

我需要在按下按钮时拍摄快照。所以在按钮处理程序中我输入了以下代码:

final SnapshotReadyCallback snapReadyCallback = new SnapshotReadyCallback() {
        Bitmap bitmap;
        @Override
        public void onSnapshotReady(Bitmap snapshot) {
            bitmap = snapshot;
            try {
                //do something with your snapshot
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    };

GoogleMap.OnMapLoadedCallback mapLoadedCallback = new GoogleMap.OnMapLoadedCallback() {
        @Override
        public void onMapLoaded() {
            gmap.snapshot(snapReadyCallback);
        }
};
gmap.setOnMapLoadedCallback(mapLoadedCallback);

这里发生的事情是我调用 Map.setOnMapLoadedCallback(),它将等到地图加载 (onMapLoaded()) 并调用 Map.snapshot()。 这将保证地图始终加载并且您不会得到白色图像。

【讨论】:

    【解决方案4】:

    我发现 map.snapshot() 方法只有在特殊情况下才能正常工作。如果调用太早,它会崩溃,如果调用太晚和设置相机后不久,它将返回错误地图图像的快照。我希望快照返回由最后给定的相机位置和折线定义的地图快照。然而,很难让 GoogleMap 类等待它是否获取了正确的图块。如果用户单击按钮进行快照很容易,因为用户知道地图何时准备就绪,如果以编程方式发生则更困难。

    如果您有 CameraPosition (LatLng, zoom),那么如果 MapFragment 是使用 GoogleMapOption 创建的,则效果很好:

    GoogleMapOptions googleMapOptions = new GoogleMapOptions();
    googleMapOptions.liteMode(true).mapType(GoogleMap.MAP_TYPE_NORMAL); // if this is what you want
    googleMapOptions.camera(new CameraPosition(new LatLng(56, 10), 11, 0, 0));
    MapFragment.newInstance(googleMapOptions);
    

    如果你还没有CameraPosition,那就更难了。如果计算相机位置以便给定标记包含在相机中,您可能还没有相机位置,因为该计算需要使用宽度/高度初始化 GoogleMap。 (鸡和蛋的问题,或者自己动手)。

    子类 MapFragment 并覆盖 onCreate

    public class FixedMapFragment extends MapFragment {
    
        public void setOncreateListener(Listener listener) {
            this.listener = listener;
        }
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            View v = super.onCreateView(inflater, container, savedInstanceState);
            if (listener != null) {
                listener.onCreate(v, mMapManager);
            }
            return v;
        }
    }
    

    然后创建您的片段,并设置您的 onCreateListener。 onCreateListener 应该更新 cameraPosition 并设置折线等。

    当 GoogleMap 上的 onLoad 被调用时,我们应该安排另一个 onLoad 来执行快照(否则我们会再次得到错误的图块)。

    private void onLoad() {
        // Set camera position and polylines here
        mMap.setOnMapLoadedCallback(new GoogleMap.OnMapLoadedCallback() {
            @Override
            public void onMapLoaded() {
                snapshot(mSnapshotCallback);
            }
        });
    }
    

    缺点:有时地图会在屏幕上闪烁“不正确”的世界地图。为了避免这种情况,我们可以隐藏地图视图,直到使用

    拍摄快照
    mapView.setVisibility(VIEW.INVISIBLE);
    

    这已在 google-maps 8.3.0 for android 上进行了测试。

    【讨论】:

      猜你喜欢
      • 2012-10-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-04
      • 1970-01-01
      • 2011-02-26
      相关资源
      最近更新 更多