/, Patches, Project tweaks, Using APIs/Targeting Android 8 and higher, continued

Targeting Android 8 and higher, continued

In my last article, I discussed the new requirements for Android apps on Google Play to target Android 8 (API level 26) and higher, and described one possible way of handling permission requests at runtime, as required when targeting Android 6 (API level 23) and higher. In this article, I describe an alternative, and also cover the requirement for apps targeting Android 7.0 (API level 24) and higher when accessing “external” URIs.

As per the last article, this article and demo was produced using Delphi Tokyo 10.2.3. The code may or may not work with earlier versions.

UPDATE (July 20th, 2018): The demo has been modified to allow for a workaround for local notifications when targeting API 26 or greater. See below for details.

TL;DR: The demo code for this article can be found in the KastriFree project, here.

Targeting an API level

There has been some confusion over what “targeting” a particular API level means. It does not mean which Android SDK you have configured in the SDK Manager in the Delphi IDE. It means what value is set for the targetSdkVersion value in the application manifest:

This is the API level at which Android will act in “compatibility mode” for. By default, Delphi sets this value to 14 (Android 4.0). The device can still have a later version of Android installed, and your application can still use API calls that apply for the installed version, however it will act as if it were at the target level. For example, an app targeting API level 14 on a device running Android 6 will not require requesting permissions at runtime.

At present, to target a particular API level, you need to manually modify the AndroidManifest.template.xml file, as described in the previous article.

A change in the method for responding to runtime permission requests

In the previous article, I devised a method of requesting permissions at runtime that required “overriding” FMXNativeActivity in the manifest. Unfortunately, that meant having to launch the application from the device manually in order to debug via the IDE. Thanks to a suggestion from Stephane Vanderclock, author of the Alcinoe library, I’ve devised a different method that removes the need to “override” the activity.

Through necessity (which will become clearer later), I have created a new class called TPermissionsRequester, which more accurately reflects what it does anyway. This replaces the TSystemHelper class, which I recommend you stop using altogether, if you choose to change to using this new solution.

When a runtime permissions request is made, the focus moves away from the application, and once the user has granted or denied permission, the application receives focus again, and the BecameActive event fires. TPermissionsRequester handles this event, and if a permissions request has been made, checks whether such permissions were granted:

procedure TPlatformPermissionsRequester.ApplicationEventMessageHandler(const Sender: TObject; const AMsg: TMessage);
  case TApplicationEventMessage(AMsg).Value.Event of

procedure TPlatformPermissionsRequester.CheckPermissionsResults;
  LResults: TPermissionResults;
  LIndex, I: Integer;
  if FRequestCode = -1 then
  SetLength(LResults, Length(FPermissions));
  for I := Low(FPermissions) to High(FPermissions) do
    LIndex := I - Low(FPermissions);
    LResults[LIndex].Permission := FPermissions[I];
    LResults[LIndex].Granted := TOSDevice.CheckPermission(FPermissions[I]);
  TOpenPermissionsRequester(PermissionsRequester).DoPermissionsResult(FRequestCode, LResults);
  FRequestCode := -1;

So all the developer needs to be concerned with is requesting the actual permissions, and handling the OnPermissionsResult event:

constructor TForm1.Create(AOwner: TComponent);
  FRequester := TPermissionsRequester.Create;
  FRequester.OnPermissionsResult := PermissionsResultHandler;

procedure TForm1.TakePhotoButtonClick(Sender: TObject);
  FRequester.RequestPermissions([cPermissionReadExternalStorage, cPermissionWriteExternalStorage, cPermissionCamera], cPermissionsCodeExternalStorage);

As TPlatformPermissionsRequester (in DW.PermissionsRequester.Android) uses TApplicationEventMessage which comes from the FMX.Platform unit, it cannot be used in a service (at least at present). That’s why TPermissonsRequester was created, and CheckPermission method has been moved to TOSDevice, so that it can be used in a service.

Note that in this demo, permissions are requested only when absolutely required (i.e. when the user wants to take a photo). This makes the application a little more user friendly than if the permissions were requested as soon as the application starts.

In the code, I am passing the string representation of the permission, e.g.

cPermissionCamera = android.permission.CAMERA;

The format for all of the “dangerous” permissions is the same, i.e. it follows the pattern: android.permission.XXXX, where XXXX is one of the “Permissions” values in this list, so you can define your own values to be passed to the RequestPermissions method in the same manner.

Note that even though you’re requesting permissions at runtime, you still need to check the checkboxes for those permissions in the Uses Permissions section of the Project Options

Accessing “external” URIs

If you have tried to target API 26, and attempted to use the TTakePhotoFromCameraAction, you would have noticed that it fails, with the error:

android.os.FileUriExposedException: file:///storage/emulated/0/test.txt exposed beyond app through Intent.getData()

From Android 7.0 (API level 24), when accessing “external” URIs, it is necessary to use the FileProvider class. Unfortunately, the code that causes the problem for TTakePhotoFromCameraAction is actually within the Java binaries (FMX.jar) that Delphi uses, so rather than expect developers to patch and recompile FMX.jar, I’ve come up with an alternative solution.

TMediaLibrary is an alternative for (at least for the present), TTakePhotoFromCameraAction. I may or may not expand on it, depending on how useful it becomes, and how Embarcadero handle the required changes. It has a single method: TakePhoto, and has event handlers for when the image is captured successfully, or when the user canceled.

  TMediaLibrary = class(TObject)
    FPlatformMediaLibrary: TCustomPlatformMediaLibrary;
    FOnCanceled: TNotifyEvent;
    FOnReceivedImage: TReceivedImageEvent;
    procedure DoCanceled;
    procedure DoReceivedImage(const AImagePath: string; const ABitmap: TBitmap);
    constructor Create;
    destructor Destroy; override;
    procedure TakePhoto;
    property OnCanceled: TNotifyEvent read FOnCanceled write FOnCanceled;
    property OnReceivedImage: TReceivedImageEvent read FOnReceivedImage write FOnReceivedImage;

Also it is currently useful only on Android, as there are no implementations for the other platforms.

TMediaLibrary makes use of a function from the newly created unit DW.Android.Helpers, called UriFromFile. This method checks what the targetSdkVersion value is, and if >= 24 it uses the FileProvider class to create a Uri from the file reference, passing in the “authority” which needs to be specified in the manifest. This is done by adding a Provider section, like this:

When using the UriFromFile function, the value specified in the manifest for android:authorities will need to match the application’s package name. This value appears in the Project Options under Version Info.

Note the entry: <meta-data android:name=”android.support.FILE_PROVIDER_PATHS” android:resource=”@xml/provider_paths”/>. This is a reference to a file that needs to be deployed with the application, called (in this case): provider_paths.xml. This is what the file looks like:

This file needs to be added to the application’s deployment using Deployment Manager, and the Remote Path value set to: res\xml\

Remember that when targeting API level 24 or greater, your app will need to request the appropriate permissions at runtime (as per the demo), before attempting to use the TakePhoto method. I had considered making TMediaLibrary handle all this automatically; perhaps in the future 🙂 You should also remember that there are a number of other “dangerous” permissions that may be used throughout Delphi (e.g. by TLocationSensor). Be sure to request permissions at runtime for any of those that require it, before you attempt to use them.

Remember also that the UriFromFile function can be used in your own code if your app needs to access “external” files. You will certainly know this is the case if your application throws the dreaded FileUriExposedException.

Taking care of the status bar

In the previous article, it had slipped past me that when changing the API target, the status bar was no longer visible!

In this demo, the workaround was to change the Fill property of the form, setting the Color to Null, and the Kind to Solid. In addition, a Rectangle is added to the form, the Align property set to Contents, and the Color property of Fill set to Whitesmoke. Now the status bar is visible again, however remember that this is just a workaround; hopefully an official solution will present itself in the next update.

Getting notified..

The demo has been updated (July 20th, 2018) to allow for a workaround for local notifications. In order for them to work however, you will need to patch the System.Android.Notification unit from the Delphi source. Details on how to do this are in the readme. Also, you will need to use new files added to KastriFree, namely:


Note also in the demo that the original android-support-v4.dex.jar is disabled. This is because the demo uses a newer version of the Android support libraries:

Are there other issues that need to be accounted for when targeting later API levels?

I’m glad you asked! At present, I’m unaware of any other issues, however my plan is to expand the demo in the future if any others come to light. If you are aware of any that are not related to what I’ve already covered, please let me know in the comments.

The demo code for this article can be found in the KastriFree project, here.

By |2018-11-23T08:10:19+00:00June 30, 2018 7:00 pm|General tips, Patches, Project tweaks, Using APIs|67 Comments

About the Author:


  1. Stiaan Pretorius July 3, 2018 at 4:25 pm - Reply

    Thank you for the article Dave. It will surely help allot. Have you posted you solution on the EMBT quality portal? I see there some issues logged there, and the guys are getting nervous. I don’t see any useful communication from EMBT regarding this issue.

    • Dave July 3, 2018 at 5:00 pm - Reply

      Can you let me know which issues in the quality portal that are affected that you know of, where I haven’t already commented about my workarounds? Thanks!

  2. JuanM July 8, 2018 at 4:07 am - Reply

    I’m sure Embarcadero read your posts. I Hope they support or sponsorize your work because I read a solution (with some problems of course) in your website several weeks before embt said any word.

    We are nervous because the countdown continues and we have no roadmap to solve this issue.

    Thank you very much Dave,and sorry, my English is not good

  3. MG July 20, 2018 at 9:56 am - Reply

    What NDK version and API version combo is able to be used? Will API 28 work ok with NDK r9c (Standard in Tokyo?)

    • Dave July 20, 2018 at 10:15 am - Reply

      API 27 (Android 8.1) works OK with it. I don’t have a device with API 28, so I could not say for sure. Perhaps someone else can check?

      • Matt July 20, 2018 at 10:53 am - Reply

        just installed NDK r17c and getting segfaults in app at TAndroidApplicationGlue.OnCreate at startup so guessing something is not compatible with Delphi with newer NDK’s, No EMB documentation on this at all. Read somewhere that someone was using NDK 14 or 15.

      • Matt July 20, 2018 at 12:30 pm - Reply

        Installing the 64 bit version of NDK seems to have worked, odd as r9c doesent look to be 64bit,
        So have API 28 and NDK r17b running our app.

        • Stefan W. August 3, 2018 at 10:54 pm - Reply

          Hello Matt,
          just a question regarding the SDK / NDK.
          Do you use SDK and NDK 17b 64 Bit downloaded from https://developer.android.com/ndk/downloads/ with Delphi Tokyo 10.2.3 and does this work?
          For some external libraries I have to update the NDK from 9 to somewhat higher but when I did I get crashes when my apps start.

  4. Kit Bayun July 25, 2018 at 5:09 am - Reply

    Android 5.0.2 errors: Invoke error: method not found:
    Project AndroidDangerousPermissions.apk raised exception class EJNIFatal with message ‘Invoke error: method not found’.

    line 288: raise EJNIFatal.CreateRes(@SJNIUnknownMethod); in unit unit Androidapi.JNIMarshal
    Delphi Tokyo

  5. […] Head over and check out the full solution for targeting Android 8 (SDK 26) with Delphi 10.2.3 Tokyo. […]

  6. […] Targeting Android 8 and higher, continued […]

  7. […] In light of this requirement, Embarcadero Technologies has announced that they plan to deliver support for Android API level 26 in their next major release of RAD Studio, 10.3. In the meantime, they suggest that their customers on Update Subscription join the upcoming 10.3 Beta. They also recommend that you take a look at Embarcadero MVP Dave Nottage’s blog post on how to target Android API level 26 with Delphi, C++Builder and RAD Studio 10.2.3 Tokyo (read it here).  […]

  8. Lucas Magalhães August 20, 2018 at 10:20 pm - Reply

    Do you know if for Delphi Berlin Aniversario version contemplates this your correction for the new permissions method?

    • Dave August 20, 2018 at 10:22 pm - Reply

      I don’t know what the Aniversario version is, however I do not use Berlin any more. Perhaps someone who does use it can check?

  9. Dêividy Alcãntara September 2, 2018 at 11:05 pm - Reply

    Hello Delphi Words, would you help me please. I’m having trouble getting “Gettubg notified”. I can not complete the last step.
    “3. Open a command prompt, change to the project folder, and execute the following command:”
    Could you tell me if you are having any problems with the procedure?

    1. Install the Patch tool from http://gnuwin32.sourceforge.net/packages/patch.htm
    Location of installation: C:\Program Files (x86)\GnuWin32\

    2. Copy System.Android.Notification.pas from the Delphi source (described above) to the demo project folder
    Copied to: D:\Embacadeiro\Projetos\KastriFree-master\KastriFree-master\Demos\AndroidAPI26\System.Android.Notification.pas

    3. Copy System.Android.Notification.10.2.3.API26.patch from the Workarounds folder in the KastriFree library (described above) to the demo project folder
    Copied to: D:\Embacadeiro\Projetos\KastriFree-master\KastriFree-master\Demos\AndroidAPI26\FMX.VirtualKeyboard.Android.10.2.3.patch

    3. Open a command prompt, change to the project folder, and execute the following command:
    1 Open CMD as administrator!
    2 I went in the project folder
    CMD – d:
    CMD – cd D:\Embacadeiro\Projetos\KastriFree-master\KastriFree-master\Demos\AndroidAPI26\

    3 \Patch System.Android.Notification.pas < System.Android.Notification.10.2.3.API26.patch
    Command executed: C:\Program Files (x86)\GnuWin32\Patch System.Android.Notification.pas < System.Android.Notification.10.2.3.API26.patch

  10. Sam September 15, 2018 at 1:24 am - Reply

    Hi Dave, brilliant solution for 10.2.3. However, have you thought of a solution concerning earlier versions of Delphi. It appears that some of the AndroidAPI units such as Androidapi.JNI.GraphicsContentViewText have changed for 10.2.3 when compared with 10.1 🙁

    • Dave September 15, 2018 at 8:13 am - Reply

      Hi Sam,

      Aside from the copyright notice, Androidapi.JNI.GraphicsContentViewText is identical between 10.1 and 10.2.3. Perhaps you mean some other unit(s)? If so, please describe exactly what is different, and what problems the differences cause.

  11. silvia September 19, 2018 at 3:24 am - Reply

    I’m lost ! I don know how o make this work. What I need is API26 requirement for Android (read external storage, push notifications).. even I dont know if i have to patch some tokio files and wich files

    1- Downloaded patch from http://gnuwin32.sourceforge.net/packages/patch.htm.. doesn´t work in w10 or at least I only see a command box.. if i write in it .. System.Android.Notification.pas < System.Android.Notification.10.2.3.API26.patch do NOTHING

    I followed all other steps (manifest,etc)

    What I missing? all… i cant go forward

    • Dave September 19, 2018 at 8:22 am - Reply

      Patch is a command-line program, i.e. you should open a command-line window to run it. As per the instructions, make a copy of System.Android.Notification.pas in the *same* folder as the demo project. It makes things easier if you copy the .patch file to the same folder, then change directory to the project folder and use this command:

      C:\Utils\patch System.Android.Notification.pas < System.Android.Notification.10.2.3.API26.patch Replacing C:\Utils with whatever folder you installed Patch in. This is the only source file that needs to be patched, and it is for Local Notifications to work in API 26+

      • silvia September 19, 2018 at 11:11 pm - Reply

        Thank you Dave. It works fine… the reason was because I was not running CMD as administrator

  12. Tom Keith September 21, 2018 at 4:27 pm - Reply

    Hi Dave, I have used the TMediaLibrary for the Camera Action fix, but it seems to rotate an image (90 deg Anticlockwise) when picture is taken in portrait on Android device, it’s OK if taken in landscape. I tried my same project on an old device (Android 4.4) where the my code will then use TTakePhotoFromCameraAction instead and the image comes in correctly in portrait (no rotation). Do you have any ideas what I can do to fix that?

    • Dave September 23, 2018 at 1:25 pm - Reply

      Hi Tom,

      Not sure why it would be doing that (it works ok on both my devices), however there’s some code in this demo:


      That shows how to obtain information about an image using the ExifInterface Java class, specifically in the GetEXIF method of TForm1 in Unit1.pas. You could modify the code in TPlatformMediaLibrary.MessageResultNotificationHandler in the DW.MediaLibrary.Android unit to make a call like this:

      LEXIF.getAttributeInt(TJExifInterface.JavaClass.TAG_ORIENTATION, -1)

      which retrieves the orientation, and compare it to TJExifInterface.JavaClass.ORIENTATION_NORMAL, TJExifInterface.JavaClass.ORIENTATION_ROTATE_180 etc. You could then use the Rotate method of the LBitmap to correct the orientation.

      I’m unable to give a complete solution right now as I am travelling at the moment and my time is a bit limited. If you get stuck, let me know and I’ll see what I can do.

  13. Tom Keith September 24, 2018 at 7:08 am - Reply

    Thanks a lot for the reply I will look into that today. Another thing we discovered is the image is very large (probably original size) compared to the old Camera Action method, any suggestions on that would be appreciated.

    • Tom Keith September 24, 2018 at 1:11 pm - Reply

      Hi Dave, using your suggestion I got the Orientation corrected if it happens to be out, and have found a way to resize the image

  14. Matt Thomas October 1, 2018 at 9:27 am - Reply

    I can’t seem to get the WRITE_SETTINGS permission to work. Even though it is checked in the permissions of the project options, when I check the app permissions within the application manager on the phone, it doesn’t show up. Other permissions – calendar, camera, etc. – they are all there, but nothing for write_settings. I want to change the screen brightness. Can someone try to get that permission working? Thanks.

    • Dave October 1, 2018 at 9:34 am - Reply

      There’s some details on how to make the permission work here:


      Though it’s in Java. If you’re unable to work it out in Delphi code, I might be able to find time to

      • Matt Thomas October 1, 2018 at 10:44 am - Reply

        In the many hours I spent searching for a solution, I ran across that web page, and I tried making the extra changes to the manifest file (the activity part)…and of course the write_settings permission was already in there….but the application manager still missing “allow modify system settings” as shown on that web page, and there is still an error when the permission requester tries to request that permission. I assume the permission requester has no chance of working if the OS doesn’t even think the app should have that permission.

        • Dave October 1, 2018 at 12:17 pm - Reply

          I was able to use the following code to enable write settings (make sure to enable Write Settings in the Permissions section of the Project Options):

            Androidapi.JNI.GraphicsContentViewText, Androidapi.JNI.Provider, Androidapi.JNI.Net, Androidapi.Helpers;
          procedure TForm1.RequestWriteSettingsButtonClick(Sender: TObject);
            if not TJSettings_System.JavaClass.canWrite(TAndroidHelper.Context) then
              ShowMessage('System says app can write settings');
          procedure TForm1.StartWritePermissionsActivity;
            LIntent: JIntent;
            LIntent := TJIntent.JavaClass.init(TJSettings.JavaClass.ACTION_MANAGE_WRITE_SETTINGS);

          The trick is to alert the user to use the “Back” button once they have changed the settings

          • Matt Thomas October 2, 2018 at 3:26 am

            Thanks! It works. It works differently than the other permissions (i.e., instead of a dialog box with allow/deny, it provides a full screen form with a toggle switch). I wonder if that is the only way in which it was intended to work for that particular permission. In any case, thanks for looking into the issue.

  15. […] In lieu of using the 10.3 beta to deliver Android API level 26 ready apps, another option is to follow Embarcadero MVP Dave Nottage’s excellent blog post on how to target Android API Level 26 with Delphi, C++Builder and RAD Studio 10.2.3 Tokyo: http://delphiworlds.com/2018/06/targeting-android-8-and-higher-continued/ […]

  16. Vilson C. Gärtner October 27, 2018 at 7:05 am - Reply

    Hi Dave, thank you very much for your article.
    By following your instructions, Play Store accepted my .apk file.
    However, I got a strange side effect: my App’s BluetoothLE component doesn’t anymore Discover any device, when searching !!!
    Restoring targetSdkVersion to it’s default value, the App finds devices again …
    Any idea about what could be the reason, or how to proceed?
    Thanks again!

    • Dave October 27, 2018 at 9:15 am - Reply

      Hi Vilson,

      In order for Bluetooth scanning to work, you need to request permissions for location services, i.e. android.permission.ACCESS_COARSE_LOCATION and android.permission.ACCESS_FINE_LOCATION

  17. Javier Garrido October 30, 2018 at 3:46 am - Reply

    Thanks for the article, Dave. I have tried to follow each step in an app that I want to compile for Android 8.0 but it reports an error in the System.Android.Notification file that I previously patched. Specifically, the error is on line 367:

    LIntent.setAction (TNotificationReceiver.ACTION_NOTIFICATION);
    [dcc32 Error] System.Android.Notification.pas (367): E2003 Undeclared identifier: ‘ACTION_NOTIFICATION’

    I suppose that in some step I have lost.

    Greetings and thanks again for the great article.

    • Dave October 30, 2018 at 4:42 pm - Reply

      Hi Javier,

      It’s very odd that the compiler would error on ACTION_NOTIFICATION, but not on TNotificationReceiver. Can you make sure that the implementation uses clause of the patched System.Android.Notification unit looks like this?:

        System.SysUtils, System.DateUtils, System.Classes, System.Messaging, System.TimeSpan,
        // DW - https://quality.embarcadero.com/browse/RSP-20565
        DW.Androidapi.JNI.App, DW.Androidapi.JNI.Support, DW.Android.Helpers, DW.NotificationReceiver;

      ..and that the DW.NotificationReceiver unit is in the compiler path?

      • Javier Garrido October 30, 2018 at 5:40 pm - Reply

        Hi Dave, thanks for answering. If I have DW.NotificationReceiver in the path of the compiler and also, when in doubt, I added the file directly in the project, but I keep reporting the error. And the file System.Android.Notification.pas seems to be correctly patched with your patch because I can see the comments with // DW …..

        Greetings and thanks.

        • Javier Garrido November 1, 2018 at 6:39 pm - Reply

          Hello Dave.- I add one more error when compiling in case it helps:

          [DCC Error] System.Android.Notification.pas(368): E2250 There is no overloaded version of ‘putExtra’ that can be called with these arguments

          Greetings and Thanks. And sorry for my poor English. I’m Spanish and I only read some English.

  18. Yuyus Nurkamal October 30, 2018 at 4:10 pm - Reply

    Dave, Why Never Enter to IF AResults.AreAllGranted ……..

    • Dave October 30, 2018 at 4:34 pm - Reply

      Does the problem occur in the demo, without any modifications, or is this your own code? If it is your own code, please provide the code so that the problem can be found.

      • Yuyus Nurkamal October 30, 2018 at 5:23 pm - Reply

        Your Demo AndroidAPI26, get Request Permission occured when Button Event Click.
        It’s my own program base on AndroidAPI26 on KastriFree, I put at Drive : https://drive.google.com/drive/folders/14Xvx8gmYajDxtoDfXamEhbdGtXhXsuQ6?usp=sharing
        It’s just First Form
        Sorry with My English

        • Dave October 30, 2018 at 5:41 pm - Reply

          Have you made sure that you have added all the permissions in the Project Options?

          Does it reach the line where AreAllGranted is called? Have you debugged into that routine to see which permissions have not been granted?

          Your English is fine 🙂 I assume from your code that you speak Indonesian? I speak it, a little

          • Yuyus Nurkamal October 30, 2018 at 7:39 pm

            OK Dave, I try again later (there’s something make be little busy), I think I was forget to check Permission list.
            Right Dave I’m Indonesia. Do You have been visit my country ? It’s supprise that you can speak Indonesia

          • Dave October 30, 2018 at 7:45 pm

            I have been in Bali for the past 6 weeks.. just going back to Australia today!

          • Yuyus Nurkamal October 31, 2018 at 12:59 am

            Dave, After I checked Uses Permission, It’s still the program never reach line …. IF AResults.AreAllGranted
            I got Request Permission for twice

  19. Ken Randall November 5, 2018 at 3:19 am - Reply

    Iam creating a PDF and then viewing it using intents but aafter following the instructions here it cannot find the pdf I’ve created. Where should I create it and do you have an example please? The user permission side of this works perfectly.

    • Dave November 5, 2018 at 7:28 am - Reply

      Hi Ken,

      I’ve sent you an email about it

  20. Robbert November 16, 2018 at 1:12 am - Reply

    Hi Dave,
    I have now successfully implemented all your solutions for targetAPI 26.
    Thanks again!

    I have some suggestions for the text and demos:

    (1) Demo project AndroidAPI26: it needs ..\..\Include to be added to the Search path (Project Options)

    (2) Regarding manifest template for TMediaLibrary: maybe better to use android:authorities=”%package%.fileprovider”
    In that case Delphi will automatically replace %package% for the package name, and people (like me;)) will not forget the .fileprovider part.

    (3) Maybe obvious, but if an app needs a dangerous permission, this permission should also be added in the manifest (by select them in Project Options, User Permisions). Maybe wise to add that to the text (if a dangerous permission is missing in the manifest, TPermissionsRequester.RequestPermissions will deny the permission without even ask for it).

    (4) Status bar: it is also wise to set the Sides property of the workaround rectangle to [], especially if the form contains transparent objects like a VertScrollbox. Otherwise you will see the black border of the workaround rectangle shining through.

    KInd regards,

    • Dave November 17, 2018 at 10:36 am - Reply

      Hi Robbert,

      Thanks for the feedback! I’ve updated the project options to include the Include folder in the search path, modified AndroidManifest.template.xml, and updated the article regarding checking the permissions in the Uses Permissions section. The background rectangle already has its sides set to [].

  21. Ivanilson Ribeiro November 17, 2018 at 6:17 am - Reply

    Can i use my Delphi Berlin to work with API 26?

  22. retxano November 20, 2018 at 1:17 am - Reply

    Hi Dave,

    Thank you very much for your post, it has been very helpful.

    I have followed your instructions and thanks to you I have managed to solve most of the problems. But I have not yet come up with the solution to admob ads notifications. The ads work in the application compiled with the ideo tokyo 10.2.3 but with your method it always returns the error: failed to load ad: 3.

    Can you help me?

    Thank you so much

  23. retxano November 20, 2018 at 5:21 pm - Reply

    Hi Dave,

    Thank you very much for your quick response.

    All these checks have already been made.
    In fact the ads, banner and interstitials, are shown both in test mode and also real with my application compiled with IDE Tokyo 10.2.3.
    However, when I implement your method, both types of ads in real mode return the error: failed to load ad: 3

    Thanks for your help,
    Best regards.

  24. retxano November 21, 2018 at 5:08 pm - Reply

    Hi Dave,

    Subject solved, your method works perfectly!!!

    The problem was that I generated a new Keystore for the application that did not match the one registered in the ad manager and returned the error.

    Sorry for the inconvenience and thank you very much for your invaluable help.

    Best regards.

  25. Danny Alexandre November 23, 2018 at 7:54 am - Reply

    Hello, Dave.

    Congratulations on your code, I also use the code to push.

    I compiled my app, uploaded it to the Play Store and it was published. In Android phones version 7 and 8 runs normal, but in versions 6 and 5 gives error and closes when open / run.

    Is this because of level 26?

    • Dave November 23, 2018 at 8:06 am - Reply

      Without knowing what the errors are, I don’t know what is causing them. Do you have a link to the app on Google Play? I have a device with Android 5.1.1

      Failing that, it would be preferable if you either used the LogCat viewer from my Codex add-in:


      Or the Monitor app from the Android SDK to view the messages from the device, if possible.

  26. Danny Alexandre November 23, 2018 at 11:39 am - Reply


    I found the error:

    When you send the apk to the Play Store, you must have configured the privacy policy, otherwise you can not send the app with the READ_PHONE_STATE permission. I had removed this permission since I thought the code “FRequester.RequestPermissions (cDangerousPermissions, 1);” would enable it. In fact enabled, but only for versions 7 and 8 of Android.

    After properly setting up the privacy policy, enabling this permission on the IDE, recompiling the app, and sending it back to the Play Store, it worked.

    Again thank you very much for your attention and willingness to help.



  27. Valber Custódioer December 3, 2018 at 3:44 pm - Reply

    Hi Dave,
    After take photo is there any way to resize the bitmap? When I try this, the app crash and restart.
    Is it possible set the resolution for the photo too? Using TParamsPhotoQuery.RequiredResolution I didn´t have success.

    Thank you for this post. It was very usefull for me.

    • Dave December 3, 2018 at 3:52 pm - Reply

      “When I try this, the app crash and restart”

      What exactly have you tried?

      I could modify the code in the DW.MediaLibrary.Android unit to resize the image to what is specified in RequiredResolution, however I am a bit short on time at the moment.

    • malinovszkyl January 7, 2019 at 11:14 pm - Reply

      I have the exact same problem. It crashes and restarts.
      The MediaLibraryReceivedImageHandler runs fine, the aImage has width/height but the app crashes.
      In the adb log I see:
      System.err: java.io.IOException: BufferedOutputStream is closed

  28. Joana January 10, 2019 at 4:29 pm - Reply

    Hi Dave.

    Thank you for your post.

    I’ve tested api26 project sample.
    In this sample, requesting permission through the ‘Request SMS Permissions’ Button works fine.

    but If I request permission when creating form, ‘PermissionsResultHandler’ function retruned before I click the Okay of permission checking alert button.
    After that I click on the permission check button ‘Okay’, no callback ‘PermissionsResultHandler’ function .

    example in Deomos – AndroidAPI26)

    constructor TForm1.Create(AOwner: TComponent);
    FRequester := TPermissionsRequester.Create;
    FRequester.OnPermissionsResult := PermissionsResultHandler;
    FRequester.RequestPermissions([cPermissionSendSMS, cPermissionReceiveSMS, cPermissionReadSMS, cPermissionReceiveMMS, cPermissionReceiveWAPPush], cPermissionsCodeSMS);

    procedure TForm1.PermissionsResultHandler(Sender: TObject; const ARequestCode: Integer; const AResults: TPermissionResults);
    case ARequestCode of
    if AResults.AreAllGranted then
    ShowMessage(‘You need to grant all required permissions for the app to be able to take photos!’);
    if AResults.AreAllGranted then
    ShowMessage(‘SMS permissions granted’)
    ShowMessage(‘You need to grant all required permissions for the app to be able to handle SMS!’);

    • Yus Kamal January 13, 2019 at 6:20 pm - Reply

      This problem as I have experienced and I have been find a solution. Try not to place FRequester.RequestPermissions on the Form Create or Form Show. I put the FRequester.RequestPermissions on the Timer and it’s works

  29. Hezekiel January 17, 2019 at 5:09 pm - Reply

    Hi Dave,

    i’m using C++ not delphi, will the work around of targeting API level 26 solution also apply for C++?


    • Dave January 17, 2019 at 6:12 pm - Reply

      It should work the same.

Leave a Reply

Show Buttons
Hide Buttons