zoukankan      html  css  js  c++  java
  • 为Delphi 10.4.2实现android拍照填坑

    最新的Delphi版本发展到10.4.2,完美支持Andriod 11,但由于Android本身的变化,在开发Android app拍照功能功能时,还是会遇到问题,但这不是Delphi本身的问题,而是你不知如何在Delphi中处理的问题。为什么会这样呢?一句话,Android本身不断变化造成的。

    今天就有朋友遇到在10.4.2下拍照出现问题,就是拍完后,点对号,不返回。

    我帮他看这个问题,确实奇怪,于是在10.4.2下改官方的例子,结果编译后在他出问题的手机上正常。

    现在把这个过程整理出来,重温一下如何用delphi实现拍照。

    1.拍照对于Delphi来说,已经做成了一个标准的Action,在Form上放置一个ActionList,然后增加一个标准的拍照:

     增加后,我们需要处理TakePhotnFormCameraAction的OnDidFinishTaking事件,即接收拍照的结果:

     这个事件代码,将拍照结果,传给imgPhotoLibraryImage,来显示照片。

    procedure TCameraRollForm.TakePhotoFromCameraAction1DidFinishTaking(
      Image: TBitmap);
    begin
      { Assign the image retrieved from the Photo Library to the TImage component. }
      imgPhotoLibraryImage.Bitmap.Assign(Image);
    end;

    2.执行拍照。这块我们要动态的申请权限。

    procedure TCameraRollForm.btnPhotoLibraryClick(Sender: TObject);
    begin
      PermissionsService.RequestPermissions([
      JStringToString(TJManifest_permission.JavaClass.READ_EXTERNAL_STORAGE),
      JStringToString(TJManifest_permission.JavaClass.WRITE_EXTERNAL_STORAGE),
      JStringToString(TJManifest_permission.JavaClass.CAMERA)],
      LoadPicturePermissionRequestResult, DisplayRationale)
    end;
    
    // Optional rationale display routine to display permission requirement rationale to the user
    procedure TCameraRollForm.DisplayRationale(Sender: TObject; const APermissions: TArray<string>; const APostRationaleProc: TProc);
    var
      I: Integer;
      RationaleMsg: string;
    begin
      for I := 0 to High(APermissions) do
      begin
        if APermissions[I] = JStringToString(TJManifest_permission.JavaClass.READ_EXTERNAL_STORAGE) then
          RationaleMsg := RationaleMsg + 'The app needs to load photo files from your device';
      end;
      // Show an explanation to the user *asynchronously* - don't block this thread waiting for the user's response!
      // After the user sees the explanation, invoke the post-rationale routine to request the permissions
      TDialogService.ShowMessage('The app needs to read a photo file from your device to show it to you',
        procedure(const AResult: TModalResult)
        begin
          APostRationaleProc;
        end)
    end;
    
    procedure TCameraRollForm.LoadPicturePermissionRequestResult(Sender: TObject; const APermissions: TArray<string>; const AGrantResults: TArray<TPermissionStatus>);
    begin
      if (Length(AGrantResults) = 3) and
         (AGrantResults[0] = TPermissionStatus.Granted) and
         (AGrantResults[1] = TPermissionStatus.Granted) and
         (AGrantResults[2] = TPermissionStatus.Granted)
         then
    //      TakePhotoFromLibraryAction1.Execute
          TakePhotoFromCameraAction1.Execute
      else
        TDialogService.ShowMessage('Cannot do photo editing because the required permissions are not granted');
    end;

     PermissionsService.RequestPermissions这个方法,请求拍照权限,请求后会执行回调函数LoadPicturePermissionRequestResult,在这个函数中,判断用户是否同意了请求的权限,如果同意,则执行拍照动作:TakePhotoFromCameraAction1.Execute

    写到这里,我不仅想,如果官方在TakePhotoFromCameraAction1.Execute中,自动请求权限该有多好,能省去我这么多麻烦,还要记得需要请求哪些权限。唉,想多了不是...

    接下来,我们要对项目做一些配置,不然拍照也不正常。

    首先,要设置Secure File Sharing为True,如下图:

    关于这项设置,我前期有写过,Delphi 10.3.1 Secure File Sharing解决应用间文件共享

    对应的这三个权限也要设置一下:

    TJManifest_permission.JavaClass.READ_EXTERNAL_STORAGE)
    TJManifest_permission.JavaClass.WRITE_EXTERNAL_STORAGE)
    TJManifest_permission.JavaClass.CAMERA)

    有两种方法,一是在Project Options中设置,如下图:

     或者,另外一种就是直接修改AndroidManifest.template.xml,增加需要的权限,实际上这两种方法的目的是一样的,第一种方法,也是由Delphi把设置的权限填加到AndroidManifest.xml文件中:

       <uses-permission android:name="android.permission.CAMERA"/>
       <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
       <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
       <uses-feature android:name="android.hardware.camera"/>
       <uses-feature android:name="android.hardware.camera.autofocus" />

    最后,对于从10.3.3升级过来的项目,我们还要在AndroidManifest.template.xml中增加一句:

    android:requestLegacyExternalStorage="true"

    上面朋友遇到的就是这个问题,其实,我前期遇到过,并且整理出来了:Delphi 10.4.1 在android平台下建立文件无权限,可以去参考一下。

    写到这里,基本上一个通用的拍照app就实现了,看似复杂,操作下来还是很简单的。当你看到这篇文章,估计我遇过的坑都在这里了,算你运气好!

     

  • 相关阅读:
    自己写CPU第五级(5)——测试逻辑、实现移动和空指令
    ERROR: The partition with /var/lib/mysql is too full! failed!
    关于精益创业理念随想
    android使用ffmpeg
    如何让格斗游戏的横版过关(2) Cocos2d-x 2.0.4
    java两个音频进入巩固期 玩的同时类似的伴奏
    Java 反射 想
    SharePoint 2013 如何使用Silverlight
    如何才能连接到你的网站访客
    写作---英语中常见的写作错误有哪些
  • 原文地址:https://www.cnblogs.com/kinglandsoft/p/14565464.html
Copyright © 2011-2022 走看看