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

如何在Delphi 11.3中调用Android 13默认地图应用?

Android 13下Delphi 11.3导航Intent失效(Receiver not found)问题解决

问题描述

在Delphi 11.3开发的Android应用中,通过Intent调用默认地图应用(Google Maps、Waze等)导航到指定经纬度的代码,在旧版Android和Delphi中正常运行,但在Android 13下点击导航按钮时持续显示“Receiver not found”提示。当前AndroidManifest.xml已配置以下位置权限:

android:targetSdkVersion="32" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />

导航按钮点击事件代码如下:

procedure TMainForm.NavigateBtnClick(Sender: TObject);
var
  {$IFDEF ANDROID}
    Intent: JIntent;  //Declares the intent object
  {$ENDIF}
  LGoogleMapsURL: String;
begin
   // Populate a string to send to Mapping app
   LGoogleMapsURL:= 'google.navigation:q=37.422219,-122.08364&amp;mode=d';
  
  {$IFDEF MSWINDOWS}
    WebBrowser1.Navigate(LGoogleMapsURL);
  {$ENDIF}

  {$IFDEF ANDROID}
      Intent := TJIntent.Create;
      Intent.setData(StrToJURI(LGoogleMapsURL));
      Intent.setAction(TJIntent.JavaClass.ACTION_VIEW);
      Intent.putExtra(TJIntent.JavaClass.EXTRA_TEXT, StringToJString(LGoogleMapsURL));
      if MainActivity.getPackageManager.queryIntentActivities(Intent, TJPackageManager.JavaClass.MATCH_DEFAULT_ONLY).size > 0 then
        begin          
          MainActivity.startActivity(Intent);
        end
      else
        ShowMessage('Receiver not found');
  {$ENDIF}
end;

请问该代码在Android 13中是否已失效,或是存在遗漏配置?

问题原因及修复方案

核心原因

Android 13对Intent的匹配逻辑更严格,当前代码存在两个关键问题:

  • 仅使用Google Maps专属的google.navigation: URI,无法被Waze等其他地图应用识别,导致queryIntentActivities找不到匹配项;
  • 冗余添加了EXTRA_TEXT参数,干扰Intent的匹配逻辑。

修复步骤

1. 改用通用geo: URI协议(推荐)

使用Android标准的地理URI协议,兼容绝大多数地图应用:

procedure TMainForm.NavigateBtnClick(Sender: TObject);
var
  {$IFDEF ANDROID}
    Intent: JIntent;
  {$ENDIF}
  LGeoURL: String;
begin
   // 标准geo协议格式:geo:纬度,经度?q=纬度,经度(目的地标签)&mode=导航模式(d=驾车/w=步行/b=骑行)
   LGeoURL := 'geo:37.422219,-122.08364?q=37.422219,-122.08364&mode=d';
  
  {$IFDEF MSWINDOWS}
    WebBrowser1.Navigate(LGeoURL);
  {$ENDIF}

  {$IFDEF ANDROID}
      // 直接通过构造函数初始化Intent,简化代码
      Intent := TJIntent.Create(TJIntent.JavaClass.ACTION_VIEW, StrToJURI(LGeoURL));
      
      if MainActivity.getPackageManager.queryIntentActivities(Intent, TJPackageManager.JavaClass.MATCH_DEFAULT_ONLY).size > 0 then
        MainActivity.startActivity(Intent)
      else
        ShowMessage('未找到支持导航的应用');
  {$ENDIF}
end;

2. 保留Google Maps专属URI并兼容其他应用

如果需要优先支持Google Maps,可保留google.navigation: URI,同时添加geo: URI作为降级方案:

procedure TMainForm.NavigateBtnClick(Sender: TObject);
var
  {$IFDEF ANDROID}
    Intent: JIntent;
  {$ENDIF}
  LGoogleMapsURL, LGeoURL: String;
begin
   LGoogleMapsURL := 'google.navigation:q=37.422219,-122.08364&mode=d';
   LGeoURL := 'geo:37.422219,-122.08364?q=37.422219,-122.08364&mode=d';
  
  {$IFDEF MSWINDOWS}
    WebBrowser1.Navigate(LGoogleMapsURL);
  {$ENDIF}

  {$IFDEF ANDROID}
      Intent := TJIntent.Create(TJIntent.JavaClass.ACTION_VIEW, StrToJURI(LGoogleMapsURL));
      
      if MainActivity.getPackageManager.queryIntentActivities(Intent, TJPackageManager.JavaClass.MATCH_DEFAULT_ONLY).size > 0 then
        MainActivity.startActivity(Intent)
      else
      begin
        // 降级使用通用geo协议
        Intent := TJIntent.Create(TJIntent.JavaClass.ACTION_VIEW, StrToJURI(LGeoURL));
        if MainActivity.getPackageManager.queryIntentActivities(Intent, TJPackageManager.JavaClass.MATCH_DEFAULT_ONLY).size > 0 then
          MainActivity.startActivity(Intent)
        else
          ShowMessage('未找到支持导航的应用');
      end;
  {$ENDIF}
end;

3. 确保运行时位置权限已授权

Android 13及以上版本中,位置权限需运行时申请,即使Manifest中已声明。可在导航前添加权限检查:

procedure TMainForm.NavigateBtnClick(Sender: TObject);
var
  {$IFDEF ANDROID}
    Intent: JIntent;
  {$ENDIF}
  LGeoURL: String;
begin
  {$IFDEF ANDROID}
    // 检查位置权限
    if not PermissionsService.IsPermissionGranted(ACCESS_FINE_LOCATION) then
    begin
      PermissionsService.RequestPermissions([ACCESS_FINE_LOCATION],
        procedure(const APermissions: TArray<string>; const AGrantResults: TArray<TPermissionStatus>)
        begin
          if AGrantResults[0] = TPermissionStatus.Granted then
            NavigateBtnClick(Sender) // 权限通过后重新执行导航逻辑
          else
            ShowMessage('需要位置权限以完成导航');
        end);
      Exit;
    end;
  {$ENDIF}

   LGeoURL := 'geo:37.422219,-122.08364?q=37.422219,-122.08364&mode=d';
  
  {$IFDEF MSWINDOWS}
    WebBrowser1.Navigate(LGeoURL);
  {$ENDIF}

  {$IFDEF ANDROID}
      Intent := TJIntent.Create(TJIntent.JavaClass.ACTION_VIEW, StrToJURI(LGeoURL));
      
      if MainActivity.getPackageManager.queryIntentActivities(Intent, TJPackageManager.JavaClass.MATCH_DEFAULT_ONLY).size > 0 then
        MainActivity.startActivity(Intent)
      else
        ShowMessage('未找到支持导航的应用');
  {$ENDIF}
end;

4. 可选:升级Target SDK版本

当前targetSdkVersion为32,升级到33(Android 13)可更好适配系统行为,无需额外权限声明,但此调整不是解决该问题的核心。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 08:23:12