我正在尝试在 Delphi Seattle 中使用 TIdHTTP.Get 下载文件。这是一个安卓应用程序,我所有的尝试都失败了。我得到的都是同样的错误“无法加载 SSL 库”。这是程序: procedure TfrmMain.DownloadPicture(const AURL: string); var MeS: TMemoryStream; cidSSL: TIdSSLIOHandlerSocketOpenSSL; cidHTTP: TIdHTTP; begin cidHTTP:= TIdHTTP.Create(nil); cidSSL:= TIdSSLIOHandlerSocketOpenSSL.Create(nil); Mes := TMemoryStream.Create; try cidHTTP.ReadTimeout := 30000; cidHTTP.IOHandler := IdSSL; cidSSL.SSLOptions.Method := sslvSSLv3; cidSSL.SSLOptions.Mode := sslmUnassigned; cidSSL.StartSSL; cidHTTP.Get(AURL, Mes); except on E : Exception do begin showmessage('Error: '+E.Message); end; end; Mes.Position := 0; frmImage.Image.Bitmap.LoadFromStream(Mes); end; 如果您没有使用 Android 6 Marshmallow,OpenSSL 应该可以在 Android 上正常工作。当你得到“could not load”错误时,你可以 也就是说,从 Android 6 Marshmallow 开始,Google 不再支持Android 上的OpenSSL。它已被名为BoringSSL的自定义分支所取代,但Indy 尚不完全支持该分支(尽管在西雅图发布后对 Indy 进行了一些与 BoringSSL 相关的更改)。因此,如果您在 Android 6 上使用 Indy SSL/TLS 时遇到问题,您可以尝试升级到最新的Github 快照,看看是否有帮助。 BoringSSL对 OpenSSL API 接口进行了一些重大更改(删除函数、更改数据类型等),因此它无法向后兼容现有的 OpenSSL 代码。但更糟糕的是,BoringSSL 使用与 OpenSSL 相同的库文件名,并在设备启动时预加载,因此无法在您的 Android 应用程序中部署自定义构建的 OpenSSL 库二进制文件。当应用程序尝试在运行时加载 OpenSSL 库文件名时,Android 将简单地使用预加载的 BoringSSL 二进制文件(无论您是否调用 Indy 的 Indy 在 Android 的 NDK 级别运行,而不是 Java 级别,因此要使 Indy 避免 BoringSSL 需要用户:
因此,目前没有已知可行的解决方法可以使 Indy SSL/TLS 在 Android 6+ 上运行。 更新:Embarcadero 论坛中的用户能够找到 https://forums./thread.jspa?threadID=211089
同一讨论中的另一位用户似乎也取得了一些成功:
更新:以下(德语)论坛讨论为注册用户提供适用于 Android(和 iOS 模拟器)的 OpenSSL 1.0.2g 二进制文件。它们不会在 Google Play 商店中显示安全警告: http://www./188736-kompilierte-openssl-bibliotheken-fuer-android.html 更新:适用于 OpenSSL 1.0.2g 的 Android 二进制文件现已在 Embarcadero 附件论坛中提供: https://forums./thread.jspa?threadID=211147 然后,要加载 OpenSSL 而不是 BoringSSL,请按照下列步骤操作:
更新:OpenSSL 1.0.1t 和 1.0.2h 二进制文件现在位于 Embarcadero 附件论坛中: https://forums./thread.jspa?threadID=211147 更新:二进制文件现已发布在 Indy 的 Fulgan 镜像上: 更新:Indy 不再使用 Fulgan 镜像来托管 OpenSSL 二进制文件。他们现在在自己的 GitHub 存储库中:
可能您有一个新的 OpenSSL 库和一个较旧的 Indy 版本。检查这个: Indy 10 - IdSMTP.Connect 引发“无法加载 SSL 库”。 我使用此代码,这有效: procedure TfPrecos.GetImageByUrl(URL: string); var Strm: TMemoryStream; vIdHTTP: TIdHTTP; cidSSL: TIdSSLIOHandlerSocketOpenSSL; begin IdOpenSSLSetLibPath(TPath.GetDocumentsPath); //libcrypto.so and libssl.so in ./assets/internal vIdHTTP.IOHandler := cidSSL; cidSSL.SSLOptions.Method := sslvSSLv23; // version 2.3 cidSSL.SSLOptions.Mode := sslmUnassigned; cidSSL.StartSSL; try vIdHTTP.Get(URL, Strm); if (Strm.Size > 0) then begin Strm.Position := 0; try Image1.Bitmap.LoadFromStream(Strm); finally end; end; finally Strm.DisposeOf; vIdHTTP.DisposeOf; end; end; |
|