You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Xamarin Forms Android:文件分享与打开问题求助

Hey there, let's tackle your Xamarin.Android issues one by one!

文件分享问题:"Error loading. The request contains no data"

The root cause here is that Intent.ExtraStream expects a Uri, not a direct byte array. Android's share Intent can't process in-memory byte arrays directly—you need to first write the bytes to a temporary file, then use a FileProvider to get a valid Uri (critical for Android 7.0+ to avoid FileUriExposedException).

Step-by-step fix:

  1. Save your byte array to a temporary cache file
  2. Configure FileProvider (if you haven't already)
  3. Pass the Uri to your share Intent with proper permissions

Code to save byte array to temp file:

private string SaveByteArrayToTempFile(byte[] fileArray, string fileName)
{
    var tempDir = Context.CacheDir;
    var tempFile = new File(tempDir, fileName);
    using (var stream = new FileStream(tempFile.AbsolutePath, FileMode.Create))
    {
        stream.Write(fileArray, 0, fileArray.Length);
    }
    return tempFile.AbsolutePath;
}

Updated share code:

byte[] fileArray = ....;
string tempFilePath = SaveByteArrayToTempFile(fileArray, "MyFile.dat");

var sharingIntent = new Intent(Intent.ActionSend);
sharingIntent.SetType("application/octet-stream");

// Get Uri via FileProvider (replace "com.yourpackage.name.fileprovider" with your app's authority)
var fileUri = FileProvider.GetUriForFile(this, "com.yourpackage.name.fileprovider", new File(tempFilePath));

// Grant temporary read permission to the receiving app
sharingIntent.AddFlags(ActivityFlags.GrantReadUriPermission);

sharingIntent.PutExtra(Intent.ExtraStream, fileUri);
StartActivity(Intent.CreateChooser(sharingIntent, "Send file"));

FileProvider configuration (add to AndroidManifest.xml):

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

Create Resources/xml/file_paths.xml:

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <cache-path name="temp_files" path="." />
</paths>

文件打开与转byte[]问题

The path you're getting from intent.Data.Path isn't a real filesystem path—it's a Content Uri (Android's file picker returns these for security starting from Android 6.0). Directly using the Path property will give you an invalid string. Instead, use ContentResolver to open an input stream from the Uri.

Code to handle both byte[] conversion and file opening:

protected override void OnActivityResult(int requestCode, Result resultCode, Intent intent)
{
    base.OnActivityResult(requestCode, resultCode, intent);
    if (resultCode == Result.Ok && intent?.Data != null)
    {
        // Option 1: Convert file to byte[]
        byte[] fileBytes = ReadFileBytesFromUri(intent.Data);
        
        // Option 2: Open the file with the default app
        OpenFileWithDefaultApp(intent.Data);
    }
}

// Helper to read byte[] from Content Uri
private byte[] ReadFileBytesFromUri(Uri uri)
{
    using (var inputStream = ContentResolver.OpenInputStream(uri))
    {
        if (inputStream == null) return null;
        
        using (var memoryStream = new MemoryStream())
        {
            inputStream.CopyTo(memoryStream);
            return memoryStream.ToArray();
        }
    }
}

// Helper to open file with default application
private void OpenFileWithDefaultApp(Uri uri)
{
    var openIntent = new Intent(Intent.ActionView);
    // Get the correct MIME type for the file
    string mimeType = ContentResolver.GetType(uri);
    openIntent.SetDataAndType(uri, mimeType);
    // Grant temporary read permission
    openIntent.AddFlags(ActivityFlags.GrantReadUriPermission);
    
    try
    {
        StartActivity(openIntent);
    }
    catch (ActivityNotFoundException)
    {
        Toast.MakeText(this, "No app found to open this file", ToastLength.Short).Show();
    }
}

This works for both your download folder Uri (/document/raw:/storage/emulated/0/Download/MyFile.dat) and SD card Uri (/document/1513-1812:MyFile.dat)—the ContentResolver handles resolving these Uri types automatically.


内容的提问来源于stack exchange,提问作者Neff

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 10:32:57