我正在尝试使用TIdHTTP下载文件。在Delphi Seattle中获取。这是一个适用于Android的应用程序,我所有的尝试都失败了。我所得到的都是相同的错误“无法加载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棉花糖,则OpenSSL在Android上应该可以正常工作。当您收到“无法加载”错误时,可以在WhichFailedToLoad()
单元中调用Indy的IdSSLOpenSSLHeaders
函数,以找出无法加载OpenSSL的原因。如果您的设备未预装OpenSSL,则可以在应用程序中部署OpenSSL二进制文件,并使用Indy的IdOpenSSLSetLibPath()
函数告诉Indy从何处加载它们。
就是说,从Android 6 Marshmallow开始,Android上为Google no longer supports OpenSSL。它已被一个名为BoringSSL的自定义派生类替换为Indy does not fully support yet(尽管在Seattle发布后对Indy进行了一些与BoringSSL相关的更改)。因此,如果您在Android 6上使用Indy SSL/TLS遇到麻烦,则可以尝试升级到最新的SVN snapshot以查看是否有帮助(在撰写本文时,当前的SVN修订版为5359)。
BoringSSL对OpenSSL API接口(interface)进行了一些重大更改(删除函数,更改数据类型等),因此它与现有的OpenSSL代码不向后兼容。但更糟糕的是,BoringSSL使用与OpenSSL相同的库文件名,并在设备启动时预加载,因此无法在您的Android应用程序中部署自定义的OpenSSL库二进制文件。当应用尝试在运行时加载OpenSSL库文件名时,Android将仅使用预加载的BoringSSL二进制文件(无论您是否调用Indy的IdOpenSSLSetLibPath()
函数)。
Indy在Android的NDK级别(而不是Java级别)上运行,因此要使Indy避免使用BoringSSL,将需要用户执行以下任一操作:
IdSSLOpenSSLHeaders_static
文件,则这应该是对Indy的.a
单元进行相关定义的微小更改。我确实知道至少有一个用户尝试此路由,但是该用户尚未成功(获取源代码以正确完全链接时出错)。 TIdStack
和TIdIOHandler
类。但这存在性能和线程问题,需要解决。 因此,目前尚没有已知可行的解决方法来使Indy SSL/TLS在Android 6+上运行。
更新:Embarcadero论坛中的用户能够找到与Indy兼容并可以在Android 6上使用的OpenSSL
.so
文件:https://forums.embarcadero.com/thread.jspa?threadID=211089
After many reports of my apps crashing if installed in Android 6 devices I've searched the net for some tips and the couple of needed .so compiled files, 1.02 version, added the two files to the play store deployment of my apps (assets\internal) and changed the Indy's path calling
IdOpenSSLSetLibPath(TPath.GetDocumentsPath)
in the OnCreate of my datamodule.
After those modifications of my code my Apps run perfectly on my brand new S7 with Android 6.0.1, and on all the other recent Android devices (tested using the Play Store deployment).
And now the Google warning pops up telling me that the OpsnSSL files deployed with my apps are not of the minimum required 1.02f version (or 1.01r).... and so my post in this forum.
...
Anyway you can download here the latest .so files, the ones that I deploy at this moment: https://drive.google.com/file/d/0B7AxqW32K0oXWW9nUk9qaFpHT0k/view?usp=sharing
同一讨论中的另一位用户似乎也取得了一些成功:
Ive been running on android 6 loading the .so libraries just fine for months. The new problem is we need to compile new versions of the openssl libraries. Cygwin is not working correctly to compile for me so im switching to a linux install to create them (if possible) https://wiki.openssl.org/index.php/Android#Build_the_OpenSSL_Library_2
heres a repository you can grab some current prebuilt ones https://github.com/emileb/OpenSSL-for-Android-Prebuilt.git
更新:以下(德语)论坛讨论为注册用户提供了Android(和iOS模拟器)的OpenSSL 1.0.2g二进制文件。它们不会在Google Play商店中显示安全警告:
http://www.delphipraxis.net/188736-kompilierte-openssl-bibliotheken-fuer-android.html
OpenSSL 1.0.2g Android.zip
OpenSSL 1.0.2g iOS Simulator.zip
更新:现在可在Embarcadero附件论坛中获得适用于OpenSSL 1.0.2g的Android二进制文件:
https://forums.embarcadero.com/thread.jspa?threadID=211147
然后,要加载OpenSSL而不是BoringSSL,请按照以下步骤操作:
.so
文件添加到您的项目部署中,并将它们设置为部署到.\assets\internal\
文件夹System.StartupCopy
单元添加为DPR的uses
子句中的第一个单元。 IdOpenSSLSetLibPath(TPath.GetDocumentsPath)
。 更新:Embarcadero附件论坛中现已提供OpenSSL 1.0.1t和1.0.2h二进制文件:
https://forums.embarcadero.com/thread.jspa?threadID=211147
更新:这些二进制文件现已发布在Indy的Fulgan镜子上:
http://indy.fulgan.com/SSL/
关于android - 在Android上使用TidHTTP时出现 "Could not load SSL library"错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37105600/