Jump to content

Creating a mobile app for Android and iOS

Recommended Posts

  • Administrators

This topic will go through all the steps that it takes to make a real mobile application for Android and iOS with Smart Mobile Studio. This first post gives some background while later I'll go deeper into details with proper examples. I've done this before three years ago. At that point I had to do a few hacks to work around problems. My plan is to make this as easy as possible in SMS and to fix any bugs that may pop up.

To make proper applications for the Android and iOS app stores, we will be using Adobe's Phonegap. It's a service that can be used to turn a html5 application to a package that you can submit to the Android or iOS store. Phonegap's free plan will most likely be enough for you: Phonegap plans

You can also install Cordova, which Phonegap actuallty is, on your own computer. If someone has done it, please feel free to contribute. However, when I did develop my own app three years ago, Phonegap worked beautifully.

So, to get that Phonegap account, sign up to the free plan. Once you've logged in, you can choose between an open-source app or a private app. Phonegap lets you use existing Git repositorys, but I'll be using a zip -file.

Now, how do you do that zip file? As an example:

  • Start Smart Mobile Studio
  • Open the Tabs, Scrolling and Listbox -demo from Featured Demos
  • Build
  • Go to the www -folder in File explorer
  • Select all files inside the www-folder and zip them



Link to post
Share on other sites
  • Administrators

After the build is done, you'll get this view. As you can see, the iOS build failed, but the Android and Windows phone were successful. iOS is a bit trickier as it requires proper keys to be created. I'll go through that process in detail in following posts.

At this point you can just click on that Android logo and download the apk-package. If you upload it to your Android phone, you can then just go to File Manager and install it.

Note, that the Android package is an unsigned package, so you need to change the developer options on your phone to let it install it. Many phones will tell you what to do right away. If not, just Google for instructions for your phone.


Link to post
Share on other sites
  • Administrators

Thank you @IElite

It looks like Phonegap has improved a lot from what it was three years ago. The config.xml file is the one that controls everything. You specify there all the versions, plugins, icons, splash screens etc.

These days it looks like it's best to actually install Phonegap on your own computer. It has new features, like Phonegap Desktop, which can create your PhoneGap project with all the necessary plugins and config files.

Link to post
Share on other sites
  • Administrators

Phonegap has a nice feature, which makes testing your Phonegap apps on your mobile devices really easy. First of all, install Phonegap and the Phonegap mobile app according to the instructions here: http://docs.phonegap.com/getting-started/

Then create a new project in Phonegap desktop and save it. I save mine in c:\pgtest and gave it the name "PhonegapTest"


Then I created a new project in Smart Mobile Studio and saved it into another folder under c:\pgtest. This PhonegapTest-Smart will contain all the source code etc. The PhonegapTest -folder contains the original project that Phonegap made with all icons, plugins, config files etc.


Next, change Smart Mobile Studio to create its www -folder inside the Phonegap project's folder:


Now you can continue programming normally in SMS, testing in the embedded chrome etc. When you want to run it in Phonegap, just click on that ">" button on Phonegap Desktop.


Start the Phonegap mobile app, change the server address to your computer's ip-address (port 3000) and click Connect. Your compiled html5 app will show up nicely. Make sure that your mobile device and your Windows computer are in the same local network and that the Windows firewall does not block the port 3000.

Link to post
Share on other sites
  • Administrators

If you want to use sql to store data inside your application, SqLite is the way to go.

Add System.SqLite to the uses clause and have a peek at these two blog posts:



I just tested and it worked fine with the current Alpha. @lennartcan correct me if I'm wrong, but I think this works in any browser and Phonegap as the SqLite was ported from C to Javascript.

Link to post
Share on other sites
  • Administrators

There were some serious problems in Smart Mobile Studio's Phonegap support. An update is available now, that actually lets us use Phonegap. Before this, it actually never got initialized :(

Once you have updated and set up the test environment to use Phonegap Client and the Phonegap mobile test app, add a Memo to a form, PhoneGapApi to the uses clause and try this:

procedure TForm1.InitializeForm;
      W3Memo1.Add('uuid: '+PhoneGap.Device.uuid + #13#10);
      W3Memo1.Add('ver: '+PhoneGap.Device.version + #13#10);
      W3Memo1.Add('model: '+PhoneGap.Device.model + #13#10);
      W3Memo1.Add('manufacturer: '+PhoneGap.Device.manufacturer + #13#10);
      W3Memo1.Add('platform: '+PhoneGap.Device.platform + #13#10);
      W3Memo1.Add('cordova: '+PhoneGap.Device.cordova + #13#10);
      W3Memo1.Add('serial: '+PhoneGap.Device.serial + #13#10);

In the normal Smart Mobile Studio you won't see anything. But when you launch this in your phone it should tell you information about your phone.

Link to post
Share on other sites
  • Administrators

Phonegap has a lot of plugins, that let you access your phone's features. As a quick example, here's how you can make your phone purr:

Add to your Phonegap project's config.xml :

<plugin name="cordova-plugin-vibration" source="npm" spec="~2.1.6" />

Cool thing about Phonegap Desktop is, that that environment automatically downloads and installs the plugins. When you run the project in Phonegap Desktop, you'll notice how the new plugin appeared in the Plugins- folder.

In Smart Mobile Studio, after the Phonegap has been initialized:


When you deal with Phonegap, make sure that you wait for that signal, that it's been properly initialized. The example I posted above expects that the form will be initialized before Phonegap is ready. In general, you should wait for the initialization once, while your app is starting and make sure to always check before calling Phonegap:

if PhoneGap.Ready then PhoneGap.Notification.vibrate(1000);


Link to post
Share on other sites
  • Administrators

There's been a few days of silence on this topic. That's because I've been working on push notifications. Something I've noticed while making this:

  • PhoneGap desktop and Phonegap build differ from each other quite a lot. Same modules, that work on the PG desktop do not work on PG build and vice versa.
  • You need to use version 1.9.4 of the phonegap-plugin-push in Phonegap Build (At least, to make it work in Android)
  • Registering of push notifications only works on Phonegap Build
  • Getting that device information and vibrating the phone works out of box on Phonegap Desktop
  • In Phonegap Build you need to add these to the config.xml-file:
	<plugin name="cordova-plugin-device" spec="~1.1.7" />
	<plugin name="cordova-plugin-vibration" spec="~2.1.6" />


Link to post
Share on other sites
  • Administrators

Attached is a demo application, which supports Push Notifications. In the zip file there are two folders:

  • PhonegapTest: Contains all the necessary files, plugins and config.xml
  • PhonegapTest-Smart: Contains the source code for Smart Mobile Studio

To use this one, you need Smart Mobile Studio or newer. You also need to have a Google Developer Account, where you create a project that uses Firebase Cloud Messaging (FCM). All the Smart Mobile Studio code also supports Google's previous GCM infrastructure as well as Apple's push notifications. However, this example is with Andrdoid.

Once you have set up everything, you need these from the Firebase Cloud Messaging settings under your project:

  • Server key: Used to send push notifications from a server app or a test web page
  • Sender ID: Used to register for push notifications from the mobile application

While I wrote this demo, push notifications did NOT work in Phonegap Desktop. So you need to create an account in Phonegap Build and use it. The account is free and it's very easy to add a new project by making a zip of the PhoneGapTest -folder and uploading the zip. When the build is ready, you can download an apk-file and install it in your phone.

When you start the app, it looks like this. If you get all that information about your device, Phonegap was initialized properly.


To register with push notifications, you need to type in your own Android SenderID and click on "Init push notifications". If you have set up everything correctly, you should get the very long and cryptic Token to the debug memo. As it's close to impossible to type it from there, you can click on "Save token" to save it on your Android device. Here we use an excellent plugin ( https://github.com/ourcodeworld/cordova-ourcodeworld-filebrowser ), which lets us browse the Android filesystem and to select where to create the file:


Once you have browsed to the right folder and typed a new name and clicked on the small disk icon, you should have a file that you can then download to your computer via an usb cable or attach to an e-mail.


Then you have to just go to http://langtutorials.com/push-notification/online-fcm-push-test/ where you can send a push notification:


You'll find all the necessary plugins and their versions in the config.xml -file inside the PhoneGapTest -folder.

While setting up the Google projects and FCM accounts might be a bit tricky, dealing with Push Notifications in Smart Mobile Studio is very easy:

  • Add PhoneGapApi to your uses-clause
  • Wait for PhoneGap to initiallize with PhoneGap.OnReady
  • Call PhoneGap.InitPushNotifications(YourSenderId, @PushInitialized, @PushReceived, @PushError) where
    • PushInitialized is a procedure which will be called once, when your app has registered
    • PushReceived will be called when a push notification is sent to your app
    • PushError will receive any errors


Link to post
Share on other sites
  • Administrators

This post is about bringing iOS to the mix. While you can create development apps in Android without much preparation, Apple is a lot more restrictive. You need an iOS Developer Account, which costs $99 per year. Without that, you can't even test or install any own apps on your own iOS devices. You'll also be told everywhere that you need a Mac computer with XCode, but you really don't need it. These instructions tell you how to work around it.

Shopping list:

  • iOS Developer Account ($99 per year)
  • iTunes installed on your Windows computer (Free)
  • OpenSSL to create the necessary keys (Free)
  • Your iPad or iPhone

First, create your private key and CSR according to these instructions: https://iandevlin.com/blog/2012/11/phonegap/building-an-ios-signing-key-for-phonegap-in-windows/

Then log on to https://developer.apple.com

Step 1:

  • Select App IDs from the left and click on the plus sign:


  • Give a name to your app: yourappname
  • Explicit App ID: com.yourdomain.yourappname
  • Select the App Services you want to use: Push Notifications
  • Continue

Step 2: Create developer certificates

  • Select Certificates from the left and click on the plus sign
  • Select iOS App Development
  • Continue
  • Upload the ios.csr -file that you created with OpenSSL
  • Continue
  • Download the ios_development.cer

Step 3: Add devices.

For this step you need to get the UDID code for your iOS device(s). You can find it by connecting your device to your computer and running iTunes and following these instructions: https://bjango.com/help/iphoneudid/

    • Select Devices/All from left and click on the plus sign
    • Give a name to your device
    • Type or copy-paste your UDID
    • Select Create device

    Step 4: Create provisioning profile

    • Select Provisioning Profiles/Development from left and click on the plus sign
    • Select the app id you created
    • Continue
    • Select your certificate
    • Continue
    • Select the iOS devices you want to install you app on
    • Continue
    • Give a name to the profile
    • Continue
    • Download the provisioning profile

    Step 5: Create ios_development.p12 with OpenSSL according to the instructions on Ian Devlin's blog (the link above)

    Step 6: Log in to Phonegap Build and submit your iOS certificate and Provisoning Profile

    • Click on the failed, red iOS build and select "add a key"
    • Give a meaningful name for the key
    • Submit your ios_Development.p12
    • Submit your Provisioning profile
    • Click on submit key

    Step 7: Unlock key

    • Click on the yellow lock
    • Type in your export password, that you created in OpenSSL

    Now Phonegap should have everything it needs to properly build an ipa package of your application. If you click on Rebuild or submit a new zip- file, the iOS version will also be built. It if is successful, you can download the ipa-package and install it on your iOS device in iTunes.


    Link to post
    Share on other sites
    • Administrators

    After writing that, I noticed that newer versions of iTunes do not install ipa-packages any more. To get around that, there are some ways: https://codeburst.io/latest-itunes-12-7-removed-the-apps-option-how-to-install-ipa-on-the-device-3c7d4a2bc788

    I myself decided to use an older version of iTunes, that you can download from that page. That let me install the PhonegapTest.ipa, which I created in Phonegap build. And guess what?

    • The app was installed in my iPad
    • It started and initialized Phonegap properly
    • I clicked on "Init push notifications", which registered itself properly and returned a Token

    What did not work:

    • Saving the token as the plugin I had used for selecting the folder is strictly Android only

    However, there are many other plugins that you can use and there's no problem defining different plugins for Android and iOS in the config.xml -file.

    But basically, your Smart Mobile Studio app is now ready to receive push notifications on both Android and iOS.


    Link to post
    Share on other sites
    • 1 year later...


    I am keen make an app for our tutors to manage their shifts. The push notification system would seem to be an ideal solution for alerting tutors that their shift-roster is available or changes have been made.


    However, the demos above are no longer available. This is an area I have zero experience in so an example demo or other helpful information would be super helpful. 

    Link to post
    Share on other sites
    • Administrators
    8 hours ago, Czar said:


    I am keen make an app for our tutors to manage their shifts. The push notification system would seem to be an ideal solution for alerting tutors that their shift-roster is available or changes have been made.


    However, the demos above are no longer available. This is an area I have zero experience in so an example demo or other helpful information would be super helpful. 

    Yes, the push notifications are a great way for alerting users.

    I'll have a look to see if anything needs to be updated and upload the demo again.

    Link to post
    Share on other sites
    • Administrators

    I've been having a look at this today. Google Play changed their requirements for generated packages. Seems like Phonegap Build does not yet have an updated push notification plugin - or the old one is not compatible with Cordova 9.0.0, which is required by Google - or the way push notifications are handled in Android these days have changed.

    These are not specifically problems with Smart Mobile Studio itself as the same issues do happen with any html5-app. I hope I can crack this or that someone else can contribute.

    On the plus side, push notifications seem to work on phonegap's mobile test client, which is helpful.

    Link to post
    Share on other sites
    • Administrators

    Took some time, but I was able to create a test apk and install it on my phone.

    First of all, set up your folders the way I did in https://forums.smartmobilestudio.com/topic/4524-creating-a-mobile-app-for-android-and-ios/?do=findComment&comment=22461

    That will let you have one folder for all the Phonegap-related stuff and another folder for your SMS app.

    Here's my config.xml, which should be in the phonegap-project's folder:

    <?xml version='1.0' encoding='utf-8'?>
    <widget id="com.smartmobilestudio.phonegaptest" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:gap="http://phonegap.com/ns/1.0">
            Push sample application that receives push notifications.
        <author email="youremail@example.com" href="https://www.smartmobilestudio.com">
            Smart Mobile Studio
    	<preference name="phonegap-version" value="cli-9.0.0" />
        <preference name="android-minSdkVersion" value="19" />
        <preference name="android-targetSdkVersion" value="28" />
        <content src="index.html" />
        <preference name="DisallowOverscroll" value="true" />
        <preference name="StatusBarOverlaysWebView" value="false" />
        <preference name="StatusBarBackgroundColor" value="#ee6e73" />
        <preference name="StatusBarStyle" value="blacktranslucent" />
        <plugin name="com.ourcodeworld.plugins.Filebrowser" spec="https://github.com/ourcodeworld/cordova-ourcodeworld-filebrowser.git" />
    	<plugin name="cordova-plugin-geolocation" />
    	<plugin name="cordova-plugin-device" />
    	<plugin name="cordova-plugin-vibration" />
    	<plugin name="cordova-plugin-file" />
        <plugin name="cordova-plugin-statusbar" source="npm" />
        <plugin name="phonegap-plugin-push" source="npm" spec="~2.2.3" />
        <plugin name="cordova-plugin-console" source="npm" />
        <plugin name="cordova-plugin-dialogs" source="npm" />
        <plugin name="cordova-plugin-whitelist" source="npm" />
        <platform name="android">
          <resource-file src="google-services.json" target="app/google-services.json" />
        <platform name="android">
            <icon density="ldpi" src="www/res/icon/android/drawable-ldpi-icon.png" />
            <icon density="mdpi" src="www/res/icon/android/drawable-mdpi-icon.png" />
            <icon density="hdpi" src="www/res/icon/android/drawable-hdpi-icon.png" />
            <icon density="xhdpi" src="www/res/icon/android/drawable-xhdpi-icon.png" />
            <icon density="xxhdpi" src="www/res/icon/android/drawable-xxhdpi-icon.png" />
            <icon density="xxxhdpi" src="www/res/icon/android/drawable-xxxhdpi-icon.png" />
            <splash density="land-ldpi" src="www/res/screen/android/drawable-land-ldpi-screen.png" />
            <splash density="land-mdpi" src="www/res/screen/android/drawable-land-mdpi-screen.png" />
            <splash density="land-hdpi" src="www/res/screen/android/drawable-land-hdpi-screen.png" />
            <splash density="land-xhdpi" src="www/res/screen/android/drawable-land-xhdpi-screen.png" />
            <splash density="land-xxhdpi" src="www/res/screen/android/drawable-land-xxhdpi-screen.png" />
            <splash density="land-xxxhdpi" src="www/res/screen/android/drawable-land-xxxhdpi-screen.png" />
            <splash density="port-ldpi" src="www/res/screen/android/drawable-port-ldpi-screen.png" />
            <splash density="port-mdpi" src="www/res/screen/android/drawable-port-mdpi-screen.png" />
            <splash density="port-hdpi" src="www/res/screen/android/drawable-port-hdpi-screen.png" />
            <splash density="port-xhdpi" src="www/res/screen/android/drawable-port-xhdpi-screen.png" />
            <splash density="port-xxhdpi" src="www/res/screen/android/drawable-port-xxhdpi-screen.png" />
            <splash density="port-xxxhdpi" src="www/res/screen/android/drawable-port-xxxhdpi-screen.png" />
        <platform name="ios">
            <icon height="57" platform="ios" src="www/res/icon/ios/icon.png" width="57" />
            <icon height="114" platform="ios" src="www/res/icon/ios/icon@2x.png" width="114" />
            <icon height="40" platform="ios" src="www/res/icon/ios/icon-40.png" width="40" />
            <icon height="80" platform="ios" src="www/res/icon/ios/icon-40@2x.png" width="80" />
            <icon height="50" platform="ios" src="www/res/icon/ios/icon-50.png" width="50" />
            <icon height="100" platform="ios" src="www/res/icon/ios/icon-50@2x.png" width="100" />
            <icon height="60" platform="ios" src="www/res/icon/ios/icon-60.png" width="60" />
            <icon height="120" platform="ios" src="www/res/icon/ios/icon-60@2x.png" width="120" />
            <icon height="180" platform="ios" src="www/res/icon/ios/icon-60@3x.png" width="180" />
            <icon height="72" platform="ios" src="www/res/icon/ios/icon-72.png" width="72" />
            <icon height="144" platform="ios" src="www/res/icon/ios/icon-72@2x.png" width="144" />
            <icon height="76" platform="ios" src="www/res/icon/ios/icon-76.png" width="76" />
            <icon height="152" platform="ios" src="www/res/icon/ios/icon-76@2x.png" width="152" />
            <icon height="29" platform="ios" src="www/res/icon/ios/icon-small.png" width="29" />
            <icon height="58" platform="ios" src="www/res/icon/ios/icon-small@2x.png" width="58" />
            <icon height="87" platform="ios" src="www/res/icon/ios/icon-small@3x.png" width="87" />
            <splash height="1136" platform="ios" src="www/res/screen/ios/Default-568h@2x~iphone.png" width="640" />
            <splash height="1334" platform="ios" src="www/res/screen/ios/Default-667h.png" width="750" />
            <splash height="2208" platform="ios" src="www/res/screen/ios/Default-736h.png" width="1242" />
            <splash height="1242" platform="ios" src="www/res/screen/ios/Default-Landscape-736h.png" width="2208" />
            <splash height="1536" platform="ios" src="www/res/screen/ios/Default-Landscape@2x~ipad.png" width="2048" />
            <splash height="768" platform="ios" src="www/res/screen/ios/Default-Landscape~ipad.png" width="1024" />
            <splash height="2048" platform="ios" src="www/res/screen/ios/Default-Portrait@2x~ipad.png" width="1536" />
            <splash height="1024" platform="ios" src="www/res/screen/ios/Default-Portrait~ipad.png" width="768" />
            <splash height="960" platform="ios" src="www/res/screen/ios/Default@2x~iphone.png" width="640" />
            <splash height="480" platform="ios" src="www/res/screen/ios/Default~iphone.png" width="320" />
        <platform name="wp8">
            <icon height="99" platform="wp8" src="www/res/icon/wp8/ApplicationIcon.png" width="99" />
            <icon height="159" platform="wp8" src="www/res/icon/wp8/Background.png" width="159" />
            <splash height="1280" platform="wp8" src="www/res/screen/wp8/screen-portrait.jpg" width="768" />
        <platform name="windows">
            <icon height="150" platform="windows" src="www/res/icon/windows/Square150x150Logo.scale-100.png" width="150" />
            <icon height="30" platform="windows" src="www/res/icon/windows/Square30x30Logo.scale-100.png" width="30" />
            <icon height="50" platform="windows" src="www/res/icon/windows/StoreLogo.scale-100.png" width="50" />
            <splash height="300" platform="windows" src="www/res/screen/windows/SplashScreen.scale-100.png" width="620" />
            <icon height="120" platform="windows" src="www/res/icon/windows/StoreLogo.scale-240.png" width="120" />
            <icon height="44" platform="windows" src="www/res/icon/windows/Square44x44Logo.scale-100.png" width="44" />
            <icon height="106" platform="windows" src="www/res/icon/windows/Square44x44Logo.scale-240.png" width="106" />
            <icon height="70" platform="windows" src="www/res/icon/windows/Square70x70Logo.scale-100.png" width="70" />
            <icon height="71" platform="windows" src="www/res/icon/windows/Square71x71Logo.scale-100.png" width="71" />
            <icon height="170" platform="windows" src="www/res/icon/windows/Square71x71Logo.scale-240.png" width="170" />
            <icon height="360" platform="windows" src="www/res/icon/windows/Square150x150Logo.scale-240.png" width="360" />
            <icon height="310" platform="windows" src="www/res/icon/windows/Square310x310Logo.scale-100.png" width="310" />
            <icon height="150" platform="windows" src="www/res/icon/windows/Wide310x150Logo.scale-100.png" width="310" />
            <icon height="360" platform="windows" src="www/res/icon/windows/Wide310x150Logo.scale-240.png" width="744" />
            <splash height="1920" platform="windows" src="www/res/screen/windows/SplashScreenPhone.scale-240.png" width="1152" />
        <access origin="*" />
        <allow-intent href="http://*/*" />
        <allow-intent href="https://*/*" />
        <allow-intent href="tel:*" />
        <allow-intent href="sms:*" />
        <allow-intent href="mailto:*" />
        <allow-intent href="geo:*" />
        <platform name="android">	    
            <allow-intent href="market:*" />
        <platform name="ios">
            <allow-intent href="itms:*" />
            <allow-intent href="itms-apps:*" />

    You also have to register your app with FCM using the advice in the link that @lynkfsjust provided. Then download the google-services.json file and save it in the folder where your config.xml is.

    Lastly, when you are installing the apk on your phone, you may need to disable Play Protect in the Play Store.

    Here's the source code I'm currently using for testing. Note, that the parts that use the file dialogs is not pretty at all. You can simply ignore those parts and the FileBrowser-plugin when you make your own implementation.

    unit Form1;
      System.Types, System.Types.Convert, System.Objects, System.Time, System.json,
      SmartCL.System, SmartCL.Time, SmartCL.Graphics, SmartCL.Components,
      SmartCL.FileUtils, SmartCL.Forms, SmartCL.Fonts, SmartCL.Theme,
      SmartCL.Borders, SmartCL.Application, SmartCL.Controls.Button, SmartCL.Controls.Label,
      SmartCL.Controls.EditBox, PhoneGapApi, SmartCL.Controls.Memo, SmartCL.Controls.Image,
      System.Device.Storage, SmartCL.Device.Storage, System.IOUtils,
      System.Streams, System.Writer, SmartCL.Dialogs, SmartCL.Geolocation;
      TForm1 = class(TW3Form)
        {$I 'Form1:intf'}
        procedure AddToLog(const Value: String);
        procedure FileDialogError(data: Variant);
        procedure InitPushNotifications(Sender: TObject);
        procedure PhoneGapReady;
        procedure PushInitialized(data: Variant);
        procedure PushReceived(data: Variant);
        procedure PushError(data: Variant);
        procedure OpenSaveDialog(Sender: TObject);
        procedure SavePushToken(NewFileName: String);
        procedure InitializeForm; override;
        procedure InitializeObject; override;
        procedure Resize; override;
    { TForm1 }
    procedure TForm1.AddToLog(const Value: String);
    procedure TForm1.InitPushNotifications(Sender: TObject);
      var Id := SenderId.Text;
      PhoneGap.InitPushNotifications(Id, @PushInitialized, @PushReceived, @PushError);
    procedure TForm1.InitializeForm;
      AddToLog('Waiting for deviceready in PhoneGap');
      SenderId.Enabled := False;
      InitPush.Enabled := False;
      SaveToken.Enabled := False;
    procedure TForm1.InitializeObject;
      {$I 'Form1:impl'}
    procedure TForm1.PhoneGapReady;
      AddToLog('uuid: '+PhoneGap.Device.uuid);
      AddToLog('version: '+PhoneGap.Device.version);
      AddToLog('model: '+PhoneGap.Device.model);
      AddToLog('manufacturer: '+PhoneGap.Device.manufacturer);
      AddToLog('platform: '+PhoneGap.Device.platform);
      AddToLog('cordova: '+PhoneGap.Device.cordova);
      AddToLog('serial: '+PhoneGap.Device.serial);
      //Where are we?
      var GL:=TW3GeoLocation.Create;
      GL.OnPosition:=procedure (Sender: TObject; Position: TW3Position)
          AddToLog('Got position!');
          AddToLog('  Time: '+FormatDateTime('dd.mm.yyyy hh:nn:ss.zzz',Position.Timestamp));
          AddToLog('  Lat: '+Variant(Position.Coords.Latitude));
          AddToLog('  Lng: '+Variant(Position.Coords.Longitude));
          AddToLog('  Alt: '+Variant(Position.Coords.Altitude));
          AddToLog('  Acc: '+Variant(Position.Coords.Accuracy));
          AddToLog('  AltAcc: '+Variant(Position.Coords.AltitudeAccuracy));
          AddToLog('  Head: '+Variant(Position.Coords.Heading));
          AddToLog('  Speed: '+Variant(Position.Coords.Speed));
      GL.OnPositionError:=procedure (Sender: TObject; Msg: TW3PositionError)
          AddToLog('Got an error');
          AddToLog('Message: '+Msg.ErrorMessage);
      SenderId.Enabled := True;
      InitPush.Enabled := True;
      InitPush.OnClick := @InitPushNotifications;
    procedure TForm1.PushInitialized(data: Variant);
      AddToLog('Push init ok');
      AddToLog('Token: '+PhoneGap.RegistrationId);
      SenderId.Enabled := False;
      InitPush.Enabled := False;
      SaveToken.Enabled := True;
      SaveToken.OnClick := @OpenSaveDialog;
    procedure TForm1.PushReceived(data: Variant);
      AddToLog('Push: '+data.message);
    procedure TForm1.PushError(data: Variant);
      AddToLog('Push error: '+data.message);
    procedure TForm1.OpenSaveDialog(Sender: TObject);
    //  Uses https://github.com/ourcodeworld/cordova-ourcodeworld-filebrowser
      procedure DoSave(data: Variant);
          success: function(data) {
          error: function(data) {
    procedure TForm1.FileDialogError(data: Variant);
      AddToLog("Error calling createFileDialog: "+data.message);
    procedure TForm1.SavePushToken(NewFileName: String);
    var NewFilePath: String;
      procedure fail(err: Variant);
        AddToLog('Error saving push notification token');
      procedure FileWriterCreated(FileWriter: Variant);
        var TokenToWrite := PhoneGap.RegistrationId;
          FileWriter.onerror = @fail;
      procedure FileCreated(fileEntry: Variant);
        AddToLog('File created');
      procedure onDirectorySuccess(dirEntry: Variant);
        AddToLog('Got directory access');
          dirEntry.getFile(NewFileName, {create: true, exclusive: false}, @FileCreated, @fail);
      AddToLog('Saving push notification token');
      //Split NewFileName to path and file
      for var a:=Length(NewFileName) downto 1 do
        if NewFileName[a]='/' then begin
          NewFilePath := copy(NewFileName,1,a);
          NewFileName := copy(NewFileName,a+1,Length(NewFileName));
        window.resolveLocalFileSystemURL(@NewFilePath, @onDirectorySuccess);
    procedure TForm1.Resize;
      var h:=ClientHeight;
      if h=0 then exit;
      var w:=ClientWidth;
      SaveToken.SetBounds(0,h-40,w,40); dec(h,40);
      InitPush.SetBounds(0,h-40,w,40); dec(h,40);
      SenderId.SetBounds(0,h-32,w,32); dec(h,32);
      Forms.RegisterForm({$I %FILE%}, TForm1);


    Link to post
    Share on other sites

    Join the conversation

    You can post now and register later. If you have an account, sign in now to post with your account.

    Reply to this topic...

    ×   Pasted as rich text.   Paste as plain text instead

      Only 75 emoji are allowed.

    ×   Your link has been automatically embedded.   Display as a link instead

    ×   Your previous content has been restored.   Clear editor

    ×   You cannot paste images directly. Upload or insert images from URL.

    • Create New...