首页 文章

使用Xamarin Forms共享图像

提问于
浏览
4

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

非常感谢

Interface:

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

Xaml:

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

Code-Behind:

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

ShareClass (in Android project):

[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"));

        }
    }
}

3 回答

  • 1

    您首先需要在 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, () => { });
            }
        }
    }
    
  • 2

    以下是我用于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"));
        }
    }
    }
    
  • 1

    这是我用于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" />
    

相关问题