0

:) I'm trying to implement screenshot service which is responsible for make a screenshot of page and share it on social media platforms which user had install or emial. As standard share toolbar. i could only achive sharing for images from ur, as below is code where i got stuck:

public class ShareImage : Activity, IShareImage
{
    public Task Share(string screenshotPath)
    {
        var path = Android.OS.Environment.GetExternalStoragePublicDirectory("Temp");

        if (!File.Exists(path.Path))
        {
            Directory.CreateDirectory(path.Path);
        }

        string absPath = path.Path + "tempfile.jpg";
        File.WriteAllBytes(absPath, GetBytes(screenshotPath));

        var _context = Android.App.Application.Context;

        Intent sendIntent = new Intent(global::Android.Content.Intent.ActionSend);

        sendIntent.PutExtra(global::Android.Content.Intent.ExtraText, "Application Name");

        sendIntent.SetType("image/*");

        sendIntent.PutExtra(Intent.ExtraStream, Android.Net.Uri.Parse("file://" + absPath));
        _context.StartActivity(Intent.CreateChooser(sendIntent, "Sharing"));
        return Task.FromResult(0);
    }

    public static byte[] GetBytes(string screenshotPath)
    {
        //var stream = new MemoryStream(await CrossScreenshot.Current.CaptureAsync());
        byte[] bytes;
        bytes = DependencyService.Get<IScreenshotService>().CaptureScreenAsync();
        return bytes;
    }
}

I implemented screenshot service for current activity which is what i demand to share.

public class ScreenshotService : IScreenshotService
{
    private Activity _currentActivity;

    public void SetActivity(Activity activity)
    {
        _currentActivity = activity;
    }
    public byte[] Caputre()
    {
        var rootView = _currentActivity.Window.DecorView.RootView;

        using (var screenshot = Bitmap.CreateBitmap(
                               rootView.Width,
                               rootView.Height,
                               Bitmap.Config.Argb8888))
        {
            var canvas = new Canvas(screenshot);
            rootView.Draw(canvas);

            using (var stream = new MemoryStream())
            {
                screenshot.Compress(Bitmap.CompressFormat.Png, 90, stream);
                return stream.ToArray();
            }
        }
    }
}

With this two services i had a problem to implment it for sharing not a url string but my current look of an page. App is throwing an exception

Object reference not set to an instance of an object.

My viewmodel

 public class MainViewModel : INotifyPropertyChanged
{
    private readonly INavigation navigation;
    public MainViewModel()
    {
        //TakeScreenshotCommand = new Command(CaptureScreenshot);
        //sample data 
        SampleImageUrl = "minusikona.png";
        ShareImageCommand = new Command(() => SharingImage());
    }

    private async void SharingImage()
    {
        try
        {
            await DependencyService.Get<IShareImage>().Share(ScreenshotImage);
        }
        catch(Exception ex)
        {
            Console.Write(ex);
            await App.Current.MainPage.DisplayAlert("Eror", "Something went wrong! ;(. Please try again later! :) ", "OK");
        }
    }

    public string SampleImageUrl { get; set; }

    public ICommand TakeScreenshotCommand { get; set; }
    public ICommand ShareImageCommand { get; set; }
    private string _screenshotImage;
    public string ScreenshotImage
    {
        get => _screenshotImage;
        set
        {
            if (_screenshotImage != value)
            {
                _screenshotImage = value;
                OnPropertyChanged("_screenshotImage");
            }
        }
    }
    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

i can't figure it. For any help how to push it further i will be so much helpfull.

Michael
  • 13
  • 2
  • When you get the byte image data, it seems that there is no conversion of the data type to use. According to the way you share the image, the address is the address, so when you take the screen to get the byte data, you must first save it to the local to get the address.https://stackoverflow.com/questions/46103368/saving-a-byte-array-as-jpg-file-in-android-device-folder – Junior Jiang Mar 05 '19 at 03:02

1 Answers1

0

Please take a look on already tested 3d party solutions like https://github.com/wilsonvargas/ScreenshotPlugin

Update:

public byte[] LoadImage(string filename)
{ 
    var image UIImage.FromFile(filename);

    using (NSData imageData = image.AsPNG()) {
      byte[] myByteArray = new Byte[imageData.Length];
   System.Runtime.InteropServices.Marshal.Copy(imageData.Bytes,myByteArray, 0, Convert.ToInt32(imageData.Length));
    return myByteArray;
 }
Yauhen Sampir
  • 1,989
  • 15
  • 16
  • i'd tried that but i couldn't find a way to attach this file to share it :( Should i use some converter from saved string path to byte ? – Michael Mar 05 '19 at 13:59