共享文件到另一个应用程序(whatsapp,电报,gmail) [英] Share file to another app (whatsapp, telegram, gmail)

查看:87
本文介绍了共享文件到另一个应用程序(whatsapp,电报,gmail)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Xamarin.Forms开发一个Android应用.

I'm developing an android app using Xamarin.Forms.

到目前为止,我在开发过程中没有发现太多困难,但是现在我认为我缺少了一些东西.

So far i did not found too much difficulties during the development, but now i think i'm missing something.

我想:

  1. 将我的应用程序中的自定义文件(* .sl)与可以处理附件的任何应用程序共享(例如whatsapp,电报,gmail ..等)
  2. 使用我的应用打开我的自定义文件(* .sl)

因此,我在网络上进行了一些挖掘,最终得到了这个结果.

So, i digged a bit around the web and ended up with this;

在我的 AndroidManifest.xml 中处理我的自定义文件

In my AndroidManifest.xml to handle my custom file

   <intent-filter>
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.BROWSABLE" />
    <category android:name="android.intent.category.DEFAULT" />
    <data android:scheme="file" />
    <data android:host="*" />
    <data android:mimeType="*/*" />
    <data android:pathPattern=".*\.sl" />
  </intent-filter>
  <intent-filter>
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.BROWSABLE" />
    <category android:name="android.intent.category.DEFAULT" />
    <data android:scheme="content" />
    <data android:mimeType="application/octet-stream" />
    <data android:mimeType="application/sl" />
  </intent-filter>

该类用作Xamarin.Forms pcl中的服务

And this class, used as a Service from my Xamarin.Forms pcl

public class ShareDroid : IShare
{
    private Context _context;
    private FileSystemExDroid _fsDroid;

    public ShareDroid()
    {
        _context = Android.App.Application.Context;
        _fsDroid = new FileSystemExDroid();
    }

    public void Show(string title, string message, string filePath)
    {
         if(!_fsDroid.FileExists(filePath))
            return;

        var extension = filePath.Substring(filePath.LastIndexOf(".", StringComparison.Ordinal) + 1).ToLower();
        var contentType = GetContentType(extension);

        var intent = new Intent(Intent.ActionSend);
        intent.SetType(contentType);
        intent.PutExtra(Intent.ExtraStream, Uri.Parse("file://" + filePath));
        intent.PutExtra(Intent.ExtraText, string.Empty);
        intent.PutExtra(Intent.ExtraSubject, message ?? string.Empty);

        var chooserIntent = Intent.CreateChooser(intent, title ?? string.Empty);
        chooserIntent.SetFlags(ActivityFlags.ClearTop);
        chooserIntent.SetFlags(ActivityFlags.NewTask);
        _context.StartActivity(chooserIntent);
    }

    private static string GetContentType(string extension)
    {
        string contentType;

        switch (extension)
        {
            case "pdf":
                contentType = "application/pdf";
                break;
            case "png":
                contentType = "image/png";
                break;
            case "sl":
                contentType = "application/sl";
                break;
            default:
                contentType = "application/octet-stream";
                break;
        }

        return contentType;
    }
}

在这里,我调用共享服务的Show方法

And here i call the Show method of my share service

private void OnShare()
{
    var fileSystem = DependencyService.Get<IFileSystemEx>();
    var serializer = DependencyService.Get<ISerializer>();
    var share = DependencyService.Get<IShare>();
    var fileName = $"{Name}_{Id}.sl";
    var path = fileSystem.CreateFilePath(fileName, SpecialFolder.Personal);
    serializer.Save(path, Model);
    share.Show(Resources.ShareViaLabel, Resources.ShareViaMessage, path);
}

当我在任何设备(未模拟)上测试该应用程序时,我得到的结果都是相同的.

When i test the app on any device (not emulated) i get the same result.

  • Gmail说附件的权限被拒绝"
  • WhatsApp和电报说不支持附件"

Resources.ShareViaMessage(简短描述)可以毫无问题地显示在目标应用程序中.

The Resources.ShareViaMessage (which is a little description) gets printed in the target app without problem.

自定义文件实际上是带有自定义扩展名(.sl)的.txt文件.

The custom file is actually a .txt file with a custom extension (.sl).

任何人都可以帮忙吗?

推荐答案

最后,我提出了一个解决方案. 我从清单中删除了意图,并在主要活动中将其编码如下:

In the end i came up with a solution. I removed the intents from the manifest, and coded them in the main activity like this:

[IntentFilter(
new[] { Intent.ActionView }, 
Categories = new [] { Intent.CategoryBrowsable, Intent.CategoryDefault }, 
DataMimeType = "text/plain",
DataPathPatterns = new []
{
    @".*\\.sl",
    @".*\\..*\\.sl",
    @".*\\..*\\..*\\.sl",
    @".*\\..*\\..*\\..*\\.sl"
})]
[IntentFilter(
new[] { Intent.ActionSend },
Categories = new[] { Intent.CategoryBrowsable, Intent.CategoryDefault },
DataMimeType = "text/plain",
DataPathPatterns = new []
{
    @".*\\.sl",
    @".*\\..*\\.sl",
    @".*\\..*\\..*\\.sl",
    @".*\\..*\\..*\\..*\\.sl"
})]

还更改了 Share.Show 方法以使用文件提供商中的uri:

also changed the Share.Show method to use the uri from the fileprovider:

public void Show(string title, string filePath)
    {
        if(!_fsDroid.FileExists(filePath))
            return;

        var fileUri = FileProvider.GetUriForFile(_context, "com.***********.******.fileprovider", new File(filePath));
        var intent = new Intent(Intent.ActionSend);
        intent.SetType("text/plain");
        intent.PutExtra(Intent.ExtraText, string.Empty);
        intent.PutExtra(Intent.ExtraStream, fileUri);
        intent.SetData(fileUri);
        intent.SetFlags(ActivityFlags.GrantReadUriPermission);
        intent.SetFlags(ActivityFlags.ClearTop);
        intent.SetFlags(ActivityFlags.NewTask);

        var chooserIntent = Intent.CreateChooser(intent, title ?? string.Empty);
        _context.StartActivity(chooserIntent);
    }

在清单中,我添加的应用标签内

In the manifest, inside the application tag i added

  <provider android:name="android.support.v4.content.FileProvider" android:authorities="com.***********.******.fileprovider" android:exported="false" android:grantUriPermissions="true">
    <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" />
  </provider>

这是我的 file_paths.xml

<paths xmlns:android="http://schemas.android.com/apk/res/android">
  <files-path name="exports" path="exports/"/>
</paths>

现在我的应用程序导出了.sl文件,whatsapp,电报,gmail和其他支持文本/普通文件的应用程序都接受了附件.

And now my application exports .sl file, and whatsapp, telegram, gmail and any other app that support text/plain file accepts the attachments.

此外,在打开/发送.sl文件时,我的应用程序已列出并可用作此类文件的默认设置.

Also, when opening/sending the .sl file my app is listed and usable as default for this kind of file.

希望这对以后的工作有所帮助:)

Hope this helps out someone else in the future :)

这篇关于共享文件到另一个应用程序(whatsapp,电报,gmail)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆