使用 Xamarin Forms 共享图像
Sharing an image using Xamarin Forms
我已经创建了一个 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, () => { });
}
}
}
这是我用于 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"));
}
}
}
这是我用于 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" />
我已经创建了一个 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, () => { });
}
}
}
这是我用于 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"));
}
}
}
这是我用于 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" />