GoogleMap快照方法返回白色图像

时间:2014-03-16 19:23:15

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

我尝试使用提到的here API获取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,因为我可以在这里切换到使用片段的一些技术问题。

4 个答案:

答案 0 :(得分:7)

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

细节: 实现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);

答案 1 :(得分:3)

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

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;

答案 2 :(得分:2)

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

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()。 这将保证地图全部加载,你不会得到白色图像。

答案 3 :(得分:1)

我发现map.snapshot()方法仅在特殊条件下才能正常工作。如果过早调用,它将崩溃,如果调用到较晚,并且在设置相机后很快将返回错误地图图像的快照。我希望快照返回由最后给定的摄像机位置和折线定义的地图的快照。然而,很难让GoogleMap类等待它获取正确的图块。如果用户点击按钮来执行快照很容易,因为用户知道地图何时就绪,如果以编程方式发生则更难。

如果您有CameraPosition(LatLng,缩放),那么如果使用GoogleMapOption创建MapFragment,它的效果会很好:

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。 (鸡蛋和鸡蛋问题,或者自己动手)。

Subclass 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上测试过。