Jump to content
COMFIED

Android Back Button (Cordova/ Phonegap)

Recommended Posts

I have built a web app using smart mobile studio and compiled to android APK on phonegap.

I'm trying to get the android back button to read a variable and either perform an action in the app or terminate the app.

The code below minimizes/ hides the android app, but doesn't terminate it.  How can I introduce a variable onBackKeyDown event and prevent app from minimizing?

 

Here is my code:

 

procedure TForm1.onDeviceReady;
begin
  receivedEvent('deviceready');
end;

 

procedure TForm1.bindEvents;
begin
     document.addEventListener('deviceready', onDeviceReady, false);

     asm
      document.addEventListener("backbutton", onBackKeyDown, false);
      function onBackKeyDown(e) {
      e.preventDefault();
}
     end;
...more code...

 

procedure TForm1.InitializeForm;
begin
  inherited;
   // this is a good place to initialize components

   bindEvents;
...more code...

Share this post


Link to post
Share on other sites
procedure TForm1.onBackKeyDown(eventObj: JEvent);
begin
  //Here do the right thing based on any variable in your app.
  //Call preventDefault if you do not want your app to close.
  eventObj.preventDefault();
end;

procedure TForm1.onDeviceReady(eventObj: JEvent);
begin
  document.addEventListener('backbutton', onBackKeyDown, false);
end;

procedure TForm1.bindEvents;
begin
  document.addEventListener('deviceready', onDeviceReady, false);
end;

Probably something like this.

Share this post


Link to post
Share on other sites

I have noted the problem - the event listener fires only once- on load, then ignores all events after that.

I am calling bindEvents in the InitializeForm;

Is there a way to listen to events as long as the app is running?

Edited by COMFIED

Share this post


Link to post
Share on other sites

DeviceReady is supposed to fire only once. That's where the example code I wrote sets the next event listener to listen to backbutton. That event listener should be active all the time when the app is running. Make sure that you don't set the backbutton-event listener before deviceready has happened.

Share this post


Link to post
Share on other sites

How can i disable back button on android chrome browser? You wrote some code below which gives errors when i compile,so  which units should i write to uses section?

 

On 1/12/2019 at 2:14 PM, jarto said:

procedure TForm1.onBackKeyDown(eventObj: JEvent);
begin
  //Here do the right thing based on any variable in your app.
  //Call preventDefault if you do not want your app to close.
  eventObj.preventDefault();
end;

procedure TForm1.onDeviceReady(eventObj: JEvent);
begin
  document.addEventListener('backbutton', onBackKeyDown, false);
end;

procedure TForm1.bindEvents;
begin
  document.addEventListener('deviceready', onDeviceReady, false);
end;

Probably something like this.

 

Share this post


Link to post
Share on other sites

@Huseyin SEKER Here's code that compiles.

unit Form1;

interface

uses 
  System.Types, System.Types.Convert, System.Objects, System.Time,
  System.IOUtils, System.Device.Storage, W3C.Dom,
  SmartCL.System, SmartCL.Time, SmartCL.Graphics, SmartCL.Components,
  SmartCL.FileUtils, SmartCL.Device.Storage, SmartCL.Forms, SmartCL.Fonts,
  SmartCL.Theme, SmartCL.Borders, SmartCL.Application;

type
  TForm1 = class(TW3Form)
  private
    {$I 'Form1:intf'}
    procedure onBackKeyDown(eventObj: JEvent);
    procedure onDeviceReady(eventObj: JEvent);
  protected
    procedure InitializeForm; override;
    procedure InitializeObject; override;
    procedure Resize; override;
  end;

implementation

{ TForm1 }

procedure TForm1.InitializeForm;
begin
  inherited;
  // this is a good place to initialize components
end;

procedure TForm1.InitializeObject;
begin
  inherited;
  {$I 'Form1:impl'}
  BrowserAPI.document.addEventListener('deviceready', @onDeviceReady, false);
end;
 
procedure TForm1.Resize;
begin
  inherited;
end;
 
procedure TForm1.onBackKeyDown(eventObj: JEvent);
begin
  //Here do the right thing based on any variable in your app.
  //Call preventDefault if you do not want your app to close.
  eventObj.preventDefault();
end;

procedure TForm1.onDeviceReady(eventObj: JEvent);
begin
  BrowserAPI.document.addEventListener('backbutton', @onBackKeyDown, false);
end;

initialization
  Forms.RegisterForm({$I %FILE%}, TForm1);
end.

 

Share this post


Link to post
Share on other sites

I tried your code but it doesn't work. I tested on android (chrome) and windows (firefox). When i press back button of my cell phone below ( near home and recent apps button) it goes back to previous page, i don't want that. I want the visitor stay on my page-my application. In windows it's not so important but in cell phones it is important.

Share this post


Link to post
Share on other sites

Hi, i searched over internet and found some usefull scripts. (Source: https://stackoverflow.com/questions/12381563/how-to-stop-browser-back-button-using-javascript )
When you add following javascript codes before </head> tag of index.html it works.

<script language="javascript">
history.pushState(null, document.title, location.href);
window.addEventListener('popstate', function (event)
{
  history.pushState(null, document.title, location.href);
});
</script>
</head>

I tested on windows (firefox and chrome) and on android cell phone (chrome browser). That's exactly what i want. When back button is pressed nothing happens and the edit boxes and information entered on the active page is not lost.

Can someone try this at iOs devices?

 

Share this post


Link to post
Share on other sites

Basically you'll want to add a history entry whenever you change forms. 

Also make up alias url's for every form. For instance 'Form1' can have an url-alias of 'index.html', 'Form2' an alias of 'bookreviews.html' etc. Every history entry links a Form (from) to an alias (to), see below. 

There is an old post on this forum (2015), but checking my last project I did this :

Put an initial history entry on startup and also initiate the main eventhandler for handling backbutton presses

unit Unit1;

interface

uses
  Pseudo.CreateForms, // auto-generated unit that creates forms during startup
  System.Types, SmartCL.System, SmartCL.Components, SmartCL.Forms, 
  SmartCL.Application;

type
  TApplication  = class(TW3CustomApplication)
    procedure ApplicationStarting; reintroduce;
  end;

implementation

uses
  Globals;

procedure TApplication.ApplicationStarting;
begin
  browserapi.window.onpopstate := procedure(e:variant) begin CBOnPopState(e); end;

  browserapi.window.history.pushState(nil,'Form1','index.html');

end;

end.

Whenever there is a change in form, add an entry to the history object

browserapi.window.history.pushState(nil,'Form1','bookreview.html');  //from Form1 to bookreview.html

The second parameter (Form1) is the 'from' Smart form-name and the third parameter is the 'to' fake url. Supposing that Form2 in this example handles the bookreviews, then at some stage users will return to Form1, at which time another history entry 'Form2'  --> 'index.html' will be added.

The handler simply reacts to the history popstate events :

Procedure CBOnPopState(e: variant);
Begin
  if (browserapi.window.location.pathname = '/')                    then GoToForm('Form1');
  if (browserapi.window.location.pathname = '/index.html')          then GoToForm('Form1');
  if (browserapi.window.location.pathname = '/bookreview.html')     then GoToForm('Form2');
...

The above is for browser projects, but should work for native android as well

Share this post


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.

Guest
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...