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

Xamarin Android应用:关联自定义扩展名文件并获取文件路径

解决Xamarin Android获取唤起应用的文件路径问题

在Android中,无法通过Environment.GetCommandLineArgs()获取文件路径,需从启动应用的Intent中提取数据,以下是具体实现步骤:

1. 在Activity中捕获启动Intent

若应用首次启动,触发OnCreate;若应用已在后台运行,新的唤起请求会触发OnNewIntent,需在两个方法中处理Intent:

protected override void OnCreate(Bundle savedInstanceState)
{
    base.OnCreate(savedInstanceState);
    ProcessLaunchIntent(Intent);
}

protected override void OnNewIntent(Intent intent)
{
    base.OnNewIntent(intent);
    ProcessLaunchIntent(intent);
}

2. 分场景处理不同Intent Action

根据你配置的Action类型,分别提取文件Uri:

private void ProcessLaunchIntent(Intent intent)
{
    if (intent == null) return;

    switch (intent.Action)
    {
        // 处理直接打开文件的场景(ActionView/ActionEdit/ActionGetContent)
        case Intent.ActionView:
        case Intent.ActionEdit:
        case Intent.ActionGetContent:
            HandleFileUri(intent.Data);
            break;

        // 处理分享文件的场景(ActionSend/ActionSendto)
        case Intent.ActionSend:
        case Intent.ActionSendto:
            var sharedUri = intent.GetParcelableExtra(Intent.ExtraStream) as Android.Net.Uri;
            HandleFileUri(sharedUri);
            break;
    }
}

3. 将Uri转换为实际文件路径

区分content://和file://两种Uri类型,通过ContentResolver处理系统媒体库的content Uri:

private void HandleFileUri(Android.Net.Uri uri)
{
    if (uri == null) return;

    string filePath = string.Empty;

    // 处理file://类型的Uri
    if (uri.Scheme.Equals("file", StringComparison.OrdinalIgnoreCase))
    {
        filePath = uri.Path;
    }
    // 处理content://类型的Uri
    else if (uri.Scheme.Equals("content", StringComparison.OrdinalIgnoreCase))
    {
        using (var cursor = ContentResolver.Query(uri, null, null, null, null))
        {
            if (cursor != null && cursor.MoveToFirst())
            {
                // 优先获取Data列的路径
                int dataColumnIndex = cursor.GetColumnIndex(MediaStore.MediaColumns.Data);
                if (dataColumnIndex != -1)
                {
                    filePath = cursor.GetString(dataColumnIndex);
                }
                // Android 10+适配:通过DocumentId转换路径
                else if (uri.Authority.Equals("com.android.providers.media.documents"))
                {
                    var docId = DocumentsContract.GetDocumentId(uri);
                    var split = docId.Split(':');
                    var contentUri = MediaStore.Files.GetContentUri("external");
                    var selection = "_id=?";
                    var selectionArgs = new[] { split[1] };

                    using (var mediaCursor = ContentResolver.Query(contentUri, new[] { MediaStore.MediaColumns.Data }, selection, selectionArgs, null))
                    {
                        if (mediaCursor != null && mediaCursor.MoveToFirst())
                        {
                            filePath = mediaCursor.GetString(mediaCursor.GetColumnIndex(MediaStore.MediaColumns.Data));
                            mediaCursor.Close();
                        }
                    }
                }
                cursor.Close();
            }
        }
    }

    // 拿到路径后执行文件打开逻辑
    if (!string.IsNullOrEmpty(filePath) && File.Exists(filePath))
    {
        OpenTargetFile(filePath);
    }
}

// 示例:文件处理逻辑
private void OpenTargetFile(string filePath)
{
    // 此处编写读取.dat/.pdfl文件的业务代码
}

4. 配置必要权限

在AndroidManifest.xml中添加文件读取权限,Android 6.0及以上需动态申请:

<!-- 基础外部存储读取权限 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<!-- Android 13+ 媒体文件权限 -->
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 16:15:11