【问题标题】:Using Google's MapView v2 in Live Wallpaper在动态壁纸中使用 Google 的 MapView v2
【发布时间】:2017-12-19 20:39:12
【问题描述】:

我已经尝试解决这个问题一段时间了。我想将 MapView v2 与我的动态壁纸一起使用,到目前为止,我的结果是黑屏,底部有一个谷歌徽标。

我的清单具有所需的权限:

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />

和元数据:

 <meta-data
        android:name="com.google.android.maps.v2.API_KEY"
        android:value="@string/google_maps_key" />

 <meta-data
        android:name="com.google.android.gms.version"
        android:value="@integer/google_play_services_version" />

我还尝试按照其他一些 MapView 相关问题中的建议更改硬件加速:

android:hardwareAccelerated="false"

我还可以确认 maps Api 密钥确实正确,因为我有一个正确渲染的 MapFragment(不是在 wallaper 服务中,而是在测试活动中):

WallpaperService.Engine 代码:

private class ENGINE extends Engine implements OnMapReadyCallback, 
GoogleMap.SnapshotReadyCallback {

    private final String LOG_TAG =  ENGINE.class.getSimpleName();
    private int width = 0;
    private int height = 0;
    private SurfaceHolder holder;
    private boolean visible;
    private Bitmap bitmap;

    private final Handler handler = new Handler();
    private final Runnable drawRunner = new Runnable() {
        @Override
        public void run() {
            draw();
        }
    };

    MapView mapView;
    GoogleMap map;
    private static final int FPS = 5000;

    @Override
    public void onCreate(SurfaceHolder surfaceHolder) {
        super.onCreate(surfaceHolder);
        this.holder = surfaceHolder;


        this.width = getDesiredMinimumWidth();
        this.height = getDesiredMinimumHeight();

        int margin = 100;
        Rect rect = new Rect();
        rect.set(margin, margin, width, height);


        mapView = new MapView(getApplicationContext());
        mapView.onCreate(new Bundle()); // could this be the problem?
        // since onCreate(null) has exact same result

        int widthSpec = View.MeasureSpec.makeMeasureSpec(rect.width(), View.MeasureSpec.EXACTLY);
        int heightSpec = View.MeasureSpec.makeMeasureSpec(rect.height(), View.MeasureSpec.EXACTLY);

        mapView.measure(widthSpec, heightSpec);
        mapView.layout(0, 0, rect.width(), rect.height());


        Log.d(LOG_TAG, "Width: " + mapView.getMeasuredWidth());
        Log.d(LOG_TAG, "Height: " + mapView.getMeasuredHeight());

        mapView.onResume();
        try {
            MapsInitializer.initialize(getApplicationContext());
        } catch (Exception e) {
            e.printStackTrace();
        }

        mapView.getMapAsync(this);
    }

    public ENGINE() {
    }

    @Override
    public void onVisibilityChanged(boolean visible) {
        this.visible = visible;
        if (visible) {
            handler.post(drawRunner);
            mapView.onResume();
        } else {
            handler.removeCallbacks(drawRunner);
            mapView.onPause();
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mapView.onDestroy();
        handler.removeCallbacks(drawRunner);
    }

    private void draw() {
        final Canvas canvas = holder.lockCanvas();
        try {
            if (canvas != null) {
                if (mapView != null) {
                    mapView.draw(canvas);
                    Log.d(LOG_TAG, "Drawing Map view on the canvas");
                } else {
                    Paint paint = new Paint();
                    paint.setColor(getColor(R.color.colorAccent));
                    paint.setStyle(Paint.Style.FILL);
                    canvas.drawPaint(paint);
                }
            }
        } finally {
            if (canvas != null)
                holder.unlockCanvasAndPost(canvas);
        }

        handler.removeCallbacks(drawRunner);
        if (visible) {
            handler.postDelayed(drawRunner, FPS);
        }
    }

    @Override
    public void onSnapshotReady(Bitmap bitmap) {
        // never reaches here
        this.bitmap = bitmap;
        Log.d(LOG_TAG, "Bitmap ready");
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {
        this.map = googleMap;

        //this.map.setMyLocationEnabled(true);

        this.map.getUiSettings().setZoomControlsEnabled(true);
        this.map.getUiSettings().setMyLocationButtonEnabled(true);
        this.map.getUiSettings().setCompassEnabled(true);
        this.map.getUiSettings().setRotateGesturesEnabled(false);
        this.map.getUiSettings().setZoomGesturesEnabled(false);

        Log.d(LOG_TAG, "Map is ready");


        double latitude = 56.875300;
        double longitude = -76.783658;


        LatLng marker = new LatLng(latitude, longitude);
        this.map.addMarker(new MarkerOptions().position(marker).title("Marker Title"));


        this.map.snapshot(this); 
        // I tried using map's snapshot to render it, however this callback never returns a value
    }

}

Logcat 没有显示任何错误,也没有任何提示可能是什么问题

07-14 10:26:39.213 3167-3167/removed.for.privacy I/Google Maps 
Android API: Google Play services package version: 11055440

07-14 10:26:39.398 3167-3195/removed.for.privacy D/OpenGLRenderer: 
endAllActiveAnimators on 0x75f689e800 (RippleDrawable) with handle 
0x75f65bede0

07-14 10:27:02.772 3167-3167/removed.for.privacy I/Google Maps 
Android API: Google Play services package version: 11055440

07-14 10:27:02.838 3167-3167/removed.for.privacy 
D/ENGINE : Width: 980

07-14 10:27:02.838 3167-3167/removed.for.privacy
D/ENGINE : Height: 1820

07-14 10:27:02.867 3167-3167/removed.for.privacy 
D/ENGINE : Map is ready

07-14 10:27:02.885 3167-3195/removed.for.privacy D/OpenGLRenderer: 
endAllActiveAnimators on 0x75f689ec00 (RippleDrawable) with handle 
0x75e6820020

07-14 10:27:02.900 3167-3167/removed.for.privacy 
D/ENGINE : Drawing Map view on the canvas

07-14 10:27:07.955 3167-3167/removed.for.privacy 
D/ENGINE : Drawing Map view on the canvas

我知道,WallpaperService 并非旨在与常规 UI 元素一起使用,但是可以使用它们,并且我成功地使用了 TextViews 等。这是故意对 MapView 施加的限制,我正在打败一匹死马吗?谢谢

【问题讨论】:

    标签: android google-maps google-maps-android-api-2 android-mapview live-wallpaper


    【解决方案1】:

    精简模式是使地图可见的唯一方法。

    mapView = new MapView(context, new GoogleMapOptions().liteMode(true));
    

    但是不能倾斜、缩放和旋转。

    【讨论】:

      【解决方案2】:

      无论如何,您可以使用Google Static Maps API 获取壁纸图片(例如在此请求中:https://maps.googleapis.com/maps/api/staticmap?center=0,0&zoom=1&scale=1&size=300x500&maptype=roadmap&format=png&visual_refresh=true),然后将其显示在壁纸上(如果需要,可以通过计时器或动作重新加载和更新屏幕) .

      【讨论】:

        【解决方案3】:

        如果您想为您的地图拍照,您可以使用以下方法。通过定义变量“路径”,您可以保存图片并在其他地方重复使用。 替代方案:您可以在内部保存位图并重复使用它。

        public void savePhoto(){
            mMap.snapshot(new GoogleMap.SnapshotReadyCallback() {
                @Override
                public void onSnapshotReady(Bitmap bitmap) {
                    FileOutputStream out = null;
                    try {
                        out = new FileOutputStream(new File(path), true);
                        bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
                    }
                    catch (Exception e) {e.printStackTrace();}
                    finally {
                        try {if (out != null) {out.close();}}
                        catch (IOException e) {e.printStackTrace();}
                        saveForm(isArea, datum, path);
                    }
                }
            });
        }
        

        从方法 OnMapLoadedCallback 中调用此方法非常重要,例如:

        mMap.setOnMapLoadedCallback(new GoogleMap.OnMapLoadedCallback() {
            @Override
            public void onMapLoaded() {savePhoto();}
        });
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多