Sunmi设备Delphi应用集成支付:Intent返回崩溃及响应接收异常
Delphi 集成第三方支付APP的Intent响应问题
问题背景
在Sunmi设备上开发的Delphi应用集成第三方支付APP时,发送Intent的代码可正常执行,但无法正确接收支付响应:
- 当
return_scheme参数值与Manifest里的android:scheme="scheme_return"一致时,支付完成后返回应用会崩溃(冻结) - 修改
return_scheme为其他值,支付完成后应用可正常打开,但接收不到正确的Intent响应,HandleIntentAction中接收到的Intent始终为nil
现有配置与代码
Manifest 配置
<intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:host="pay-response" android:scheme="scheme_return" /> </intent-filter>
发送Intent的代码
uri :='payment-app://pay?return_scheme=scheme_return&amount=' + valorTotal + '&transaction_type=debit'; Intent := TJIntent.JavaClass.init(TJIntent.JavaClass.ACTION_VIEW, TJnet_Uri.JavaClass.parse(StringToJString(TIdURI.URLEncode(uri)))); SharedActivity.startActivity(Intent);
补充:接收Intent的代码
procedure TForm1.FormCreate(Sender: TObject); var AppEventService: IFMXApplicationEventService; begin if TPlatformServices.Current.SupportsPlatformService(IFMXApplicationEventService, AppEventService) then AppEventService.SetApplicationEventHandler(HandleAppEvent); MainActivity.registerIntentAction(TJIntent.JavaClass.ACTION_VIEW); TMessageManager.DefaultManager.SubscribeToMessage(TMessageReceivedNotification, HandleActivityMessage); end; procedure TForm1.HandleActivityMessage(const Sender: TObject; const M: TMessage); begin if M is TMessageReceivedNotification then HandleIntentAction(TMessageReceivedNotification(M).Value); end; function TForm1.HandleAppEvent(AAppEvent: TApplicationEvent; AContext: TObject): Boolean; var StartupIntent: JIntent; begin Result := False; if AAppEvent = TApplicationEvent.BecameActive then begin StartupIntent := MainActivity.getIntent; if StartupIntent <> nil then HandleIntentAction(StartupIntent); end; end; function TForm1.HandleIntentAction(const Data: JIntent): Boolean; var Extras: JBundle; begin Result := False; if Data <> nil then begin Memo1.ClearContent; Extras := Data.getExtras; if Extras <> nil then Memo1.Text := JStringToString(Extras.getString(TJIntent.JavaClass.EXTRA_TEXT)); Invalidate; end; end;
问题分析与解决方案
核心问题点
- Intent响应匹配冲突:当
return_scheme与Manifest中配置的scheme一致时,支付APP返回的Intent会直接触发应用的启动逻辑,但Delphi的Activity生命周期处理中,重复获取Intent导致线程阻塞或资源冲突,引发崩溃。 - Intent获取方式错误:当前代码通过
MainActivity.getIntent()获取的是启动Intent,而非支付APP返回的新Intent;且未正确处理onNewIntent回调,导致无法接收支付响应。
修复步骤
1. 调整Manifest配置(确保唯一性)
为避免scheme冲突,建议将自定义scheme设置为更唯一的值(比如包含应用包名前缀),例如:
<data android:host="pay-response" android:scheme="myapp-scheme-return" />
同时同步修改发送Intent时的return_scheme参数值。
2. 正确处理onNewIntent回调
Delphi中需要通过重写Activity的onNewIntent方法来接收新的Intent(支付响应),而不是仅依赖启动Intent或应用激活事件:
// 在Form类中添加以下代码,重写Activity的onNewIntent procedure onNewIntent(Intent: JIntent); override; // 实现部分 procedure TForm1.onNewIntent(Intent: JIntent); begin inherited; // 设置当前Intent为新接收的Intent,避免后续获取旧的启动Intent MainActivity.setIntent(Intent); // 处理支付响应 HandleIntentAction(Intent); end;
3. 修正Intent处理逻辑
支付APP返回的响应数据通常包含在Intent的Data(URI)中,而非Extras的EXTRA_TEXT里,需要调整HandleIntentAction方法:
function TForm1.HandleIntentAction(const Data: JIntent): Boolean; var IntentUri: JUri; UriString: string; begin Result := False; if Assigned(Data) then begin Memo1.ClearContent; IntentUri := Data.getData; if Assigned(IntentUri) then begin UriString := JStringToString(IntentUri.toString); Memo1.Text := UriString; // 解析URI中的支付参数,比如交易状态、订单号等 // 示例:提取transaction_status参数 // var Status: string; // Status := JStringToString(IntentUri.getQueryParameter(StringToJString('transaction_status'))); end; Invalidate; end; end;
4. 移除冗余的Intent注册
如果已经重写onNewIntent,可以移除MainActivity.registerIntentAction和TMessageManager的订阅,避免重复处理:
// 移除以下两行代码 // MainActivity.registerIntentAction(TJIntent.JavaClass.ACTION_VIEW); // TMessageManager.DefaultManager.SubscribeToMessage(TMessageReceivedNotification, HandleActivityMessage);
额外注意事项
- 测试时确保支付APP返回的URI格式与Manifest中的
data配置完全匹配(scheme、host一致) - Sunmi设备部分机型存在系统级的Intent拦截,需确认应用Manifest配置正确,无需特殊权限
内容的提问来源于stack exchange,提问作者Rene Sá
相关产品推荐
相关产品推荐

