简体   繁体   中英

Share raw resources Xamarin Android

I'm trying to add the possibility of sharing files through other applications, but I can not do it.

I am interested in being able to do it through Whatsapp and telegram, but when I try it says "unsuported format" or similar errors.

            System.IO.Stream inputStream= data.context.Resources.OpenRawResource(data.context.Resources.GetIdentifier(path, "raw", data.context.ApplicationContext.PackageName));

            var sharingIntent = new Intent();
            sharingIntent.SetAction(Intent.ActionSend);
            sharingIntent.PutExtra(Intent.ExtraStream, ReadFully(inputStream));
            sharingIntent.SetType("audio/*");

            data.context.StartActivity(Intent.CreateChooser(sharingIntent, "Share..."));

And the conversion to byte[]

     public static byte[] ReadFully(System.IO.Stream input)
    {
        byte[] buffer = new byte[16 * 1024];
        using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
        {
            int read;
            while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
            {
                ms.Write(buffer, 0, read);
            }
            return ms.ToArray();
        }
    }

Thank you!

I am interested in being able to do it through Whatsapp and telegram, but when I try it says "unsuported format" or similar errors.

From your codes, you are trying to share a big byte array, which is neither supported nor recommended. The correct way to do that is to copy the audio file from internal storage to external storage and share the Uri of it to other app:

protected override void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);

        // Set our view from the "main" layout resource
        SetContentView (Resource.Layout.Main);

        //Create a new file in the exteranl storage and copy the file from assets folder to external storage folder
        Java.IO.File dstFile = new Java.IO.File(Environment.ExternalStorageDirectory.Path + "/TestSound.mp3");
        dstFile.CreateNewFile();
        var inputStream = new FileInputStream(Assets.OpenFd("fileName.mp3").FileDescriptor);
        var outputStream = new FileOutputStream(dstFile);
        CopyFile(inputStream,outputStream);

        //to let system scan the audio file and detect it
        Intent intent = new Intent(Intent.ActionMediaScannerScanFile);
        intent.SetData(Uri.FromFile(dstFile));
        this.SendBroadcast(intent);

        //share the Uri of the file
        var sharingIntent = new Intent();
        sharingIntent.SetAction(Intent.ActionSend);
        sharingIntent.PutExtra(Intent.ExtraStream, Uri.FromFile(dstFile));
        sharingIntent.SetType("audio/*");

        this.StartActivity(Intent.CreateChooser(sharingIntent, "Share..."));
    }

    public void CopyFile(FileInputStream inputStream,FileOutputStream outputStream)
    {
        //FileChannel inChannel = new FileInputStream(src).Channel;
        FileChannel inChannel = inputStream.Channel;
        FileChannel outChannel = outputStream.Channel;
        try
        {
            inChannel.TransferTo(0, inChannel.Size(), outChannel);
        }
        finally
        {
            if (inChannel != null)
            {
                inChannel.Close();
            }

            if (outChannel != null)
            {
                outChannel.Close();
            }
        }
    }

Update:

If the audio files are in Resources/raw folder, you can use following codes to get the FileInputStream:

//My_Heart_Will_Go_On.mp3 in Resources/raw folder
AssetFileDescriptor descripter = this.Resources.OpenRawResourceFd(Resource.Raw.My_Heart_Will_Go_On);
var inputStream = new FileInputStream(descripter.FileDescriptor);

Notes: if Visual Studio didn't update Resource.Designer.cs for Resource.Raw.resourceName , you can manually update the Resource.Designer.cs like below:

[System.CodeDom.Compiler.GeneratedCodeAttribute("Xamarin.Android.Build.Tasks", "1.0.0.0")]
public partial class Resource
{
   ...
   public partial class Raw
    {

        static Raw()
        {
            global::Android.Runtime.ResourceIdManager.UpdateIdValues();
        }

        private Raw()
        {
        }
    }
}

Partial class Raw won't get overrided when rebuild the project.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM