locked
Google map screenshot always black screen RRS feed

  • Question

  • User345525 posted

    I want to take google map screenshot in my xamarin PCL Project. The map is displaying perfectly. But when i try to take a screenshot it is displaying a black screen for the map part. But extra part of the screen is capture perfectly. When i try to take screenshot from another app, i can take perfectly. I am using the below code.

    My interface

    public interface IScreenshotService { Task<byte[]> Capture(); } ` public class ScreenshotService : IScreenshotService { public static Activity Activity { get; set; }

    public async System.Threading.Tasks.Task<byte[]> Capture()
    {
        if (Activity == null)
        {
            throw new Exception("You have to set ScreenshotManager.Activity in your Android project");
        }
    
        var view = Activity.Window.DecorView;
        view.DrawingCacheEnabled = true;
    
        Bitmap bitmap = view.GetDrawingCache(true);
    
        byte[] bitmapData;
    
        using (var stream = new MemoryStream())
        {
            bitmap.Compress(Bitmap.CompressFormat.Png, 0, stream);
            bitmapData = stream.ToArray();
        }
    
        return bitmapData;
    }
    

    }

    `

    Code to for calling function

    byte[] screenshotData = await DependencyService.Get<IScreenshotService>().Capture();

    Monday, March 4, 2019 9:56 AM

All replies

  • User53115 posted

    Android Documentation:

    public void setDrawingCacheEnabled (boolean enabled)

    This method was deprecated in API level 28. The view drawing cache was largely made obsolete with the introduction of hardware-accelerated rendering in API 11. With hardware-acceleration, intermediate cache layers are largely unnecessary and can easily result in a net loss in performance due to the cost of creating and updating the layer. In the rare cases where caching layers are useful, such as for alpha animations, setLayerType(int, Paint) handles this with hardware rendering. For software-rendered snapshots of a small part of the View hierarchy or individual Views it is recommended to create a Canvas from either a Bitmap or Picture and call draw(Canvas) on the View. However these software-rendered usages are discouraged and have compatibility issues with hardware-only rendering features such as Config.HARDWARE bitmaps, real-time shadows, and outline clipping. For screenshots of the UI for feedback reports or unit testing the PixelCopy API is recommended.

    Monday, March 4, 2019 6:02 PM
  • User345525 posted

    i have already included view.DrawingCacheEnabled = true;

    in my code. Please take a look.

    Tuesday, March 5, 2019 12:43 PM
  • User105578 posted

    Hi Goutham, Did you find any answer ?

    Thursday, September 19, 2019 2:01 AM
  • User52818 posted

    I am having the same issues. Did you find a solution?

    Monday, April 13, 2020 9:04 AM
  • User395383 posted

    Hello guys, Somebody solve this problem Thanks to Noahan from stackoverflow. I can't belive i didnt see the answer he sent in 2019.

    Code:

    public class ScreenShotManager : IScreenShotManager { public static Activity Activity { get; set; }

        public async Task<byte[]> CaptureMapAsync(Map map)
        {
            if (Activity == null)
            {
                throw new Exception("You have to set ScreenshotManager.Activity in your Android project");
            }
    
            var renderer = Platform.GetRenderer(map);
            Platform.SetRenderer(map, renderer);
    
            var viewRenderer = renderer.View;
            var mapRenderer = (MapRenderer)viewRenderer;
            var mapView = mapRenderer.Control;
    
            var mapDownloaderTask = new TaskCompletionSource<byte[]>();
            mapView.GetMapAsync(new OnMapReadyCallback(m =>
            {
                mapDownloaderTask.SetResult(m);
            }));
    
            return await mapDownloaderTask.Task;
        }
    }
    
    internal class OnMapReadyCallback : Java.Lang.Object, IOnMapReadyCallback
    {
        readonly Action<byte[]> handler;
    
        public OnMapReadyCallback(Action<byte[]> handler)
        {
            this.handler = handler;
        }
    
        void IOnMapReadyCallback.OnMapReady(GoogleMap googleMap)
        {
            googleMap.Snapshot(new SnapshotMapCallBack(handler));
        }
    }
    
    internal class SnapshotMapCallBack : Java.Lang.Object, GoogleMap.ISnapshotReadyCallback
    {
        readonly Action<byte[]> handler;
    
        public SnapshotMapCallBack(Action<byte[]> handler)
        {
            this.handler = handler;
        }
    
        public void OnSnapshotReady(Bitmap snapshot)
        {
            using (var stream = new MemoryStream())
            {
                snapshot.Compress(Bitmap.CompressFormat.Png, 0, stream);
                byte[] bitmapData = stream.ToArray();
                handler?.Invoke(bitmapData);
            }
        }
    }
    

    }

    I tried the code and it works perfectly :)

    Thursday, June 25, 2020 12:14 AM