如何在iOS和Android上使用RAD Studio FireMonkey启动导航应用程序?



我知道我可以在iOS 6中使用maps.apple.com/?q=Firehouse+Subs这样的URL以编程方式打开地图应用程序,但我如何才能使其与FireMonkey一起工作?我可以把它放到一个网络浏览器中,但它只是显示谷歌地图的网络界面。我也知道这不会在Android上工作,但我可以使用一个意图来处理,但FireMonkey似乎也没有暴露这一点。

更新:进一步的研究表明,这可能是暂时不可能的,即使我写了一些特定平台的代码。这个答案说,如果没有Java的参与,就不能触发意图。是否还有一种方法可以将URL发送到iOS与c++打开导航?我没有多少iOS开发经验

所以结果是URL是两个操作系统的答案。我能够通过一些辅助函数向操作系统发送URL来打开导航。我在这里的一个博客上找到了这个源代码。它是用Delphi编写的,但事实证明,您可以将Delphi文件添加到您的项目中,在c++中编译#include "filename.hpp",并使用您在Delphi中创建的函数。

unit OpenViewUrl;
interface
uses System.Sensors;
// URLEncode is performed on the URL
// so you need to format it   protocol://path
function OpenURL(const URL: string; const DisplayError: Boolean = False): Boolean;
function OpenNavigation(const Q: string): Boolean; overload;
function OpenNavigation(const Q: string; const Coord: TLocationCoord2D): Boolean; overload;
implementation
uses
  IdURI, SysUtils, Classes, FMX.Dialogs
{$IFDEF ANDROID}
  , FMX.Helpers.Android, Androidapi.JNI.GraphicsContentViewText,
  Androidapi.JNI.Net, Androidapi.JNI.JavaTypes, Androidapi.Helpers;
{$ELSE}
{$IFDEF IOS}
  , iOSapi.Foundation, FMX.Helpers.iOS, Macapi.Helpers;
{$ELSE};
{$ENDIF IOS}
{$ENDIF ANDROID}

function OpenURL(const URL: string; const DisplayError: Boolean = False): Boolean;
{$IFDEF ANDROID}
var
  Intent: JIntent;
begin
// There may be an issue with the geo: prefix and URLEncode.
// will need to research
  Intent := TJIntent.JavaClass.init(TJIntent.JavaClass.ACTION_VIEW,
    //TJnet_Uri.JavaClass.parse(StringToJString(TIdURI.URLEncode(URL))));
    TJnet_Uri.JavaClass.parse(StringToJString(URL)));
  try
    SharedActivity.startActivity(Intent);
    exit(true);
  except
    on e: Exception do
    begin
      if DisplayError then ShowMessage('Error: ' + e.Message);
      exit(false);
    end;
  end;
end;
{$ELSE}
{$IFDEF IOS}
var
  NSU: NSUrl;
begin
  // iOS doesn't like spaces, so URL encode is important.
  // NSU := StrToNSUrl(TIdURI.URLEncode(URL));
  NSU := StrToNSUrl(URL);
  if SharedApplication.canOpenURL(NSU) then
    exit(SharedApplication.openUrl(NSU))
  else
  begin
    if DisplayError then
      ShowMessage('Error: Opening "' + URL + '" not supported.');
    exit(false);
  end;
end;
{$ELSE}
begin
  raise Exception.Create('Not supported!');
end;
{$ENDIF IOS}
{$ENDIF ANDROID}

function OpenNavigation(const Q: string): Boolean;
var Coord: TLocationCoord2D;
begin
  Coord.Latitude := 0.0;
  Coord.Longitude := 0.0;
  OpenNavigation(Q, Coord);
end;

function OpenNavigation(const Q: string; const Coord: TLocationCoord2D): Boolean;
var
  CoordString: String;
begin
  //Open in Google Maps
  {$IFDEF ANDROID}
  exit(OpenURL('http://maps.google.com/?q=' + Q));
  {$ELSE}
  //In iOS, if Google Maps is installed, use it, otherwise, use Apple Maps
  //If we have coordinates, use them as the start address
  {$IFDEF IOS}
  //Get a string of the longitute and latitute seperated by a comma if set
  if (Coord.Latitude <> 0.0) or (Coord.Longitude <> 0.0) then
  begin
    CoordString := Coord.Latitude.ToString + ',' + Coord.Longitude.ToString;
  end
  else begin
    CoordString := '';
  end;
  if not OpenURL('comgooglemaps://?daddr=' + Q) then
  begin
    if (0.0 < CoordString.Length) then
    begin
      exit(OpenURL('http://maps.apple.com/?daddr=' + Q + '&saddr=loc:' + CoordString));
    end
    else begin
      exit(OpenURL('http://maps.apple.com/?daddr=' + Q));
    end;
  end
  else begin
    exit(true);
  end;
  {$ELSE}
  //Unsupported platform
  exit(false);
  {$ENDIF IOS}
  {$ENDIF ANDROID}
end;

end.

最后一个函数是我添加的。它会根据操作系统打开地图应用程序,并选择一组坐标来导航,如果使用苹果地图,因为它不像谷歌地图那样处理它。我还没能在iOS上测试谷歌地图,如果有人能,请告诉我。

#include <fmx.h>
#include <System.IOUtils.hpp>
#include <Androidapi.JNI.GraphicsContentViewText.hpp>
#include <Androidapi.JNI.Net.hpp>
#include <Androidapi.Helpers.hpp>
#include <FMX.Helpers.Android.hpp>
void __fastcall TForm4::Button1Click(TObject *Sender)
{
   String url = "geo:0,0?q=Manchester";
   _di_JIntent Intent = TJIntent::JavaClass->init(TJIntent::JavaClass->ACTION_VIEW,TJnet_Uri::JavaClass->parse(StringToJString(url)));
    SharedActivity()->startActivity(Intent);
}
我希望上面的代码对你有帮助。这在我的应用程序上确实有效。只要记住输入你想要导航的地方,而不是曼彻斯特……它可以是邮政编码或地点如果你愿意你也可以在geo后面传递纬度和姿态而不是0,0

最新更新