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

Dart Uri.parse解析特定格式Intent失败,求Flutter/Dart解决方案

Flutter/Dart 解析特殊格式Intent链接的解决方案

对接外部服务返回的Intent链接时,部分特殊格式的链接无法通过Dart原生的Uri.parse解析,比如:

intent://%7B"CD":"test","TK":"value"%7D/#Intent;package=com.example.appname;scheme=appname;end

无论是否调用Uri.decodeFull解码,都会抛出FormatException,但Android原生的Intent.parseUri(intentUrl, Intent.URI_INTENT_SCHEME)可以正常解析,以下是两种可行的处理方案:

方案1:手动拆分解析Intent结构

Android Intent链接有固定的格式规则,可以手动拆分各部分进行解析:

  • 先以#Intent;为分隔符,拆分出data部分和参数部分
  • 对data部分做解码处理,提取核心内容
  • 对参数部分按;分割后,拆分键值对

示例代码:

String intentUrl = 'intent://%7B"CD":"test","TK":"value"%7D/#Intent;package=com.example.appname;scheme=appname;end';

// 拆分Intent的data和参数部分
List<String> splitParts = intentUrl.split('#Intent;');
if (splitParts.length != 2) {
  throw FormatException('不符合Intent链接格式');
}

// 处理data部分:去掉前缀+解码
String rawData = splitParts[0].replaceFirst('intent://', '');
String decodedData = Uri.decodeFull(rawData);
// decodedData 结果:{"CD":"test","TK":"value"}

// 处理参数部分:去掉末尾的;end,拆分键值对
String paramsRaw = splitParts[1].replaceAll(';end', '');
List<String> paramPairs = paramsRaw.split(';');
Map<String, String> intentParams = {};
for (String pair in paramPairs) {
  List<String> keyValue = pair.split('=');
  if (keyValue.length == 2) {
    intentParams[keyValue[0]] = keyValue[1];
  }
}
// intentParams 结果:{"package": "com.example.appname", "scheme": "appname"}

方案2:调用Android原生解析能力

如果你的Flutter应用仅针对Android平台,或者需要完全复用原生的解析逻辑,可以通过MethodChannel调用Android原生代码,直接使用Intent.parseUri解析后返回结果给Dart层。

第一步:Android端配置MethodChannel

在MainActivity.kt中添加通道逻辑:

import android.content.Intent
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel

class MainActivity : FlutterActivity() {
    private val CHANNEL = "com.example.intent.parser"

    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->
            when (call.method) {
                "parseIntentUrl" -> {
                    val url = call.argument<String>("url") ?: run {
                        result.error("参数错误", "Intent链接不能为空", null)
                        return@setMethodCallHandler
                    }
                    try {
                        val intent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME)
                        val resultMap = mutableMapOf<String, String?>().apply {
                            put("data", intent.dataString)
                            put("package", intent.`package`)
                            put("scheme", intent.scheme)
                            // 可根据需求添加更多字段,比如action、category等
                        }
                        result.success(resultMap)
                    } catch (e: Exception) {
                        result.error("解析失败", e.message, null)
                    }
                }
                else -> result.notImplemented()
            }
        }
    }
}

第二步:Dart层调用原生方法

import 'package:flutter/services.dart';

class AndroidIntentParser {
  static const MethodChannel _channel = MethodChannel('com.example.intent.parser');

  static Future<Map<String, dynamic>?> parseIntent(String url) async {
    try {
      final result = await _channel.invokeMethod<Map<String, dynamic>>(
        'parseIntentUrl',
        {'url': url},
      );
      return result;
    } on PlatformException catch (e) {
      print("解析Intent出错:${e.message}");
      return null;
    }
  }
}

// 使用示例
void main() async {
  String targetUrl = 'intent://%7B"CD":"test","TK":"value"%7D/#Intent;package=com.example.appname;scheme=appname;end';
  var parsedData = await AndroidIntentParser.parseIntent(targetUrl);
  print(parsedData);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 08:45:38