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

Google Pixel设备上Xamarin.Forms应用导出功能异常求助

Fix for Mobi File Export to Kindle on Google Pixel (Xamarin.Forms)

Hey Cheran, let's tackle this issue you're facing with your Xamarin.Forms app on Google Pixel devices. I've gone through your code and the problem description, and here are the key fixes to get the mobi file sharing to Kindle working properly:

1. Fix the Incorrect MIME Type

Your code hardcodes the MIME type to application/pdf, but you're trying to share a mobi file. Kindle won't recognize this type, which is likely part of the issue. Use the correct MIME type for mobi files:

  • application/x-mobipocket-ebook (standard mobi type)
  • Or application/vnd.amazon.mobi8-ebook (for newer Kindle formats)

You can also dynamically detect the MIME type using MimeTypeMap to avoid hardcoding:

string extension = MimeTypeMap.GetFileExtensionFromUrl(Android.Net.Uri.FromFile(new Java.IO.File(mobileFileName)).ToString());
string mimeType = MimeTypeMap.Singleton.GetMimeTypeFromExtension(extension);

2. Replace file:// URI with FileProvider (Critical for Android 7.0+)

Google Pixel devices run newer Android versions (API 24+), which block cross-app access to file:// URIs for security reasons. You need to use FileProvider to generate a content:// URI instead:

Step 1: Register FileProvider in AndroidManifest.xml

Add this inside the <application> tag:

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

Step 2: Create file_paths.xml in Resources/xml

If the xml directory doesn't exist, create it first. Then add this content to map your file storage path:

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- Adjust the path based on where your mobi files are stored -->
    <external-files-path name="app_files" path="." />
    <!-- Use <external-path> if files are in public external storage -->
</paths>

Step 3: Generate the Content URI in Code

Replace your file:// URI generation with this:

var file = new Java.IO.File(mobileFileName);
var contentUri = FileProvider.GetUriForFile(context, context.PackageName + ".fileprovider", file);
// Grant read permission to the target app
sendIntent.AddFlags(ActivityFlags.GrantReadUriPermission);

3. Clean Up Your Intent Setup

Your current code has several redundant or incorrect settings:

  • You hardcode SetPackage("com.google.android.apps.docs"), which limits sharing to Google Docs only (not Kindle). Remove this line unless you specifically want to target Google Docs.
  • You set Intent.ExtraStream twice (once on sendIntent, once on chooserIntent). Only set it on the base sendIntent.
  • The shareIntentsLists is empty in your code, so that block does nothing. If you want to manually filter apps, use PackageManager.QueryIntentActivities correctly.

Corrected Code Snippet

Here's the revised code incorporating all fixes:

var mobileFileName = Path.Combine(path, m_documentName);
var file = new Java.IO.File(mobileFileName);

// Get correct MIME type for mobi
string extension = MimeTypeMap.GetFileExtensionFromUrl(Android.Net.Uri.FromFile(file).ToString());
string mimeType = MimeTypeMap.Singleton.GetMimeTypeFromExtension(extension);

Intent sendIntent = new Intent(Intent.ActionSend);
sendIntent.SetType(mimeType);

// Use FileProvider for secure URI
var contentUri = FileProvider.GetUriForFile(context, context.PackageName + ".fileprovider", file);
sendIntent.PutExtra(Intent.ExtraStream, contentUri);
sendIntent.AddFlags(ActivityFlags.GrantReadUriPermission);

// Optional: If you want to target Kindle specifically, uncomment this line
// sendIntent.SetPackage("com.amazon.kindle");

// Build the chooser
Intent chooserIntent = Intent.CreateChooser(sendIntent, "Share with");
chooserIntent.SetFlags(ActivityFlags.NewTask | ActivityFlags.ClearTop);

// Optional: Manually add apps to the chooser (using QueryIntentActivities)
var resolveInfoList = context.PackageManager.QueryIntentActivities(sendIntent, PackageInfoFlags.MatchDefaultOnly);
var shareIntentsLists = new List<Intent>();

foreach (var resolveInfo in resolveInfoList)
{
    var targetIntent = new Intent(Intent.ActionSend);
    targetIntent.SetType(mimeType);
    targetIntent.PutExtra(Intent.ExtraStream, contentUri);
    targetIntent.SetPackage(resolveInfo.ActivityInfo.PackageName);
    targetIntent.AddFlags(ActivityFlags.GrantReadUriPermission);
    shareIntentsLists.Add(targetIntent);
}

if (shareIntentsLists.Count > 0)
{
    chooserIntent.PutExtra(Intent.ExtraInitialIntents, shareIntentsLists.ToArray());
}

context.StartActivity(chooserIntent);

Why This Works on Other Devices but Not Pixel

Most older Android devices don't enforce the file:// URI restriction as strictly as newer Pixel devices (which run recent Android versions). The incorrect MIME type also prevents Kindle from recognizing the file as a valid ebook, even if the URI worked.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:59:41