使用 Xamarin 窗体共享映像



我已经创建了一个Xamarin Forms(PCL(解决方案,目前我专注于Android项目。我正在尝试使用依赖项服务实现图像共享。这些图像位于 Android 项目的可绘制文件夹中。但是,每次我运行下面的代码时,应用程序都会崩溃并显示:发生了未经处理的异常。我已经检查了输出日志,但没有什么突出的。有人能够查看我的代码并告诉我其中是否有错误吗?

非常感谢

接口:

public interface IShare
{
    void Share(ImageSource imageSource);
}

Xaml:

<ContentPage.Content>
    <Image x:Name="LogoImage" Source="icon.png"/>
</ContentPage.Content>

代码隐藏:

private void Action_Clicked(object sender, EventArgs e)
{
    DependencyService.Get<IShare>().Share(LogoImage.Source);
}

ShareClass(在Android项目中(:

[assembly: Dependency(typeof(ShareClass))]
namespace MyProject.Droid
{
    public class ShareClass : Activity, IShare
    {
        public async void Share(ImageSource imageSource)
        {
            var intent = new Intent(Intent.ActionSend);
            intent.SetType("image/png");
            var handler = new ImageLoaderSourceHandler();
            var bitmap = await handler.LoadImageAsync(imageSource, this);
            var path = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDownloads
                + Java.IO.File.Separator + "logo.png");
            using (var os = new System.IO.FileStream(path.AbsolutePath, FileMode.Create))
            {
                bitmap.Compress(Bitmap.CompressFormat.Png, 100, os);
            }
            intent.PutExtra(Intent.ExtraStream, Android.Net.Uri.FromFile(path));
            Forms.Context.StartActivity(Intent.CreateChooser(intent, "Share Image"));
        }
    }
}

您首先需要在AndroidManifest.xml中添加权限。

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"  />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

Xamarin.Android

[assembly:Dependency(typeof(ShareClass))]
namespace ShareDemo.Droid
{
    public class ShareClass : Activity, IShare
    {
        public async void Share(string subject, string message, ImageSource image)
        {
            Intent intent = new Intent(Intent.ActionSend);
            //intent.PutExtra(Intent.ExtraSubject, subject);
            intent.PutExtra(Intent.ExtraText, message);
            intent.SetType("image/png");
            ImageLoaderSourceHandler handler = new 
            ImageLoaderSourceHandler();
            Bitmap bitmap = await handler.LoadImageAsync(image, this);
            Java.IO.File path = Environment.GetExternalStoragePublicDirectory(Environment.DirectoryDownloads + Java.IO.File.Separator + "logo.png");
            using (System.IO.FileStream os = new System.IO.FileStream(path.AbsolutePath, System.IO.FileMode.Create))
            {
                bitmap.Compress(Bitmap.CompressFormat.Png, 100, os);
            }
            intent.PutExtra(Intent.ExtraStream, Android.Net.Uri.FromFile(path));
            Forms.Context.StartActivity(Intent.CreateChooser(intent, "Share Image"));
        }
    }
}

Xamarin.iOS

[assembly: Dependency(typeof(ShareClass))]
namespace ShareSample.iOS
{
    public class ShareClass : IShare
    {
        public async void Share(string subject, string message, ImageSource image)
        {
            var handler = new ImageLoaderSourceHandler();
            var uiImage = await handler.LoadImageAsync(image);
            var img = NSObject.FromObject(uiImage);
            var mess = NSObject.FromObject(message);
            var activityItems = new[] { mess, img };
            var activityController = new UIActivityViewController(activityItems, null);
            var topController = UIApplication.SharedApplication.KeyWindow.RootViewController;
            while (topController.PresentedViewController != null)
            {
                topController = topController.PresentedViewController;
            }
            topController.PresentViewController(activityController, true, () => { });
        }
    }
}

这是我用于Android实现的内容

 public Task Share(string url)
        {
            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(url));
            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 url)
        {
            byte[] arry;
            using (var webClient = new WebClient())
            {
                arry = webClient.DownloadData(url);
            }
            return arry;
        }

作为我的 targetSdkVersion>24,我将以下两行添加到 MainActivity.cs以允许其他应用程序访问文件。

    StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
    StrictMode.SetVmPolicy(builder.Build());

以下是在 AndroidManifest 中允许的权限.xml

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

这是我用于 ShareClass 的代码,以使共享意图最终发挥作用,希望它对某人有所帮助:

[assembly: Xamarin.Forms.Dependency(typeof(ShareClass))]
namespace MyProject.Droid
{
public class ShareClass: MainActivity, IShare
{
    public async void Share(ImageSource imageSource)
    {
        var intent = new Intent(Intent.ActionSend);
        intent.SetType("image/jpeg");
        IImageSourceHandler handler;
        if (imageSource is FileImageSource)
        {
            handler = new FileImageSourceHandler();
        }
        else if (imageSource is StreamImageSource)
        {
            handler = new StreamImagesourceHandler(); // sic
        }
        else if (imageSource is UriImageSource)
        {
            handler = new ImageLoaderSourceHandler(); // sic
        }
        else
        {
            throw new NotImplementedException();
        }
        var bitmap = await handler.LoadImageAsync(imageSource, CrossCurrentActivity.Current.Activity);
        Java.IO.File path = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDownloads
            + Java.IO.File.Separator + "MyDiagram.jpg");
        using (System.IO.FileStream os = new System.IO.FileStream(path.AbsolutePath, System.IO.FileMode.Create))
        {
            bitmap.Compress(Bitmap.CompressFormat.Jpeg, 100, os);
        }
        intent.AddFlags(ActivityFlags.GrantReadUriPermission);
        intent.AddFlags(ActivityFlags.GrantWriteUriPermission);
        intent.PutExtra(Intent.ExtraStream, FileProvider.GetUriForFile(CrossCurrentActivity.Current.Activity, "com.mypackagename.fileprovider", path));
        CrossCurrentActivity.Current.Activity.StartActivity(Intent.CreateChooser(intent, "Share Image"));
    }
}
}

最新更新