Cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Physical Button - Exit App

ANSWERED

We have three physical buttons, and some "control" on the right hand two buttons.

 

Is it possible to place an onclick/onactivate event hook onto the left hand button?

 

For example, we want confirmation from the user that they actually do want to exit the application, rather than lose all their collected activity data.

 

Thanks

Best Answer
0 Votes
1 BEST ANSWER

Accepted Solutions

 

Just put together a little test to remap the "back" button to the "top" button.

 

So it is entirely possible to prevent accidental exit from the application.

 

Thanks to those who helped out on this Smiley Very Happy

 

import document from "document";
import { me } from "appbit";


document.onkeypress = function(e) {
  console.log("Key pressed: " + e.key);
  e.preventDefault();
    if (e.key==="up") {
      console.log("trapped");
      me.exit();
  }

 Have updated this post to show a full solution in the hope it helps someone out in the community:

 

app/index.js

 

import document from "document";
import { me } from "appbit";
import clock from "clock";

let runningPage = document.getElementById("runningPage");
let exitPage = document.getElementById("exitPage");
let timeDisplay = document.getElementById("time");
let dateDisplay = document.getElementById("date");
let btnyes = document.getElementById("btn-yes");
btnyes.onclick = function(evt) {
me.exit();
}
let btnno = document.getElementById("btn-no");
btnno.onclick = function(evt) {
runningPage.style.display="inline";
exitPage.style.display="none";
}

runningPage.style.display="inline";
exitPage.style.display="none";

document.onkeypress = function(e) {
e.preventDefault();
if (e.key=="up" && exitPage.style.display=="inline") {
me.exit();
}
if (e.key==="back" || e.key==="down") {
if (exitPage.style.display==="inline") {
runningPage.style.display="inline";
exitPage.style.display="none";
} else {
runningPage.style.display="none";
exitPage.style.display="inline";
}
}

}


clock.granularity = "seconds";
clock.ontick = () => showData();

function showData() {
let myDate=new Date();
let secs=zeroPad(myDate.getSeconds());
let mins=zeroPad(myDate.getMinutes());
let hrs=myDate.getHours();
let day=zeroPad(myDate.getDate());
let month=zeroPad(myDate.getMonth()+1);
let year=zeroPad(myDate.getFullYear());
timeDisplay.text=`${hrs}:${mins}:${secs}`;
dateDisplay.text=`${day}/${month}/${year}`;
}

function zeroPad(i) {
if (i < 10) {
i = "0" + i;
}
return i;
}

 

 

resources/index.gui

 

<svg> 
<svg id="runningPage">
<rect id="background2" pointer-events="none" />
<text y="110" x="50%" id="Title" font-family="System-Regular" fill="yellow" font-size="45" font-weight="bold" text-anchor="middle">Clock</text>
<text y="160" x="50%" id="time" font-family="System-Regular" fill="white" font-size="40" font-weight="bold" text-length="20" text-anchor="middle">Time: </text>
<text y="195" x="50%" id="date" font-family="System-Regular" fill="white" font-size="40" font-weight="bold" text-length="20" text-anchor="middle">Date: </text>
</svg>
<svg id="exitPage">
<text y="110" x="50%" id="Title" font-family="System-Regular" fill="yellow" font-size="45" font-weight="bold" text-anchor="middle">Exit: Are you sure?</text>
<svg y="$">
<use id="btn-yes" href="#square-button-toggle" x="50%" fill="fb-green">
<set href="#text" attributeName="text-buffer" to="Yes" />
</use>
<use id="btn-no" href="#square-button-toggle" value="1" fill="fb-red">
<set href="#text" attributeName="text-buffer" to="No" />
</use>
</svg>
</svg>
</svg>

 

 

resource/widgets.gui

 

<svg>
<defs>
<link rel="import" href="/mnt/sysassets/widgets_common.gui" />
<link rel="import" href="/mnt/sysassets/widgets/square_button_widget.gui" />
<link rel="import" href="/mnt/sysassets/widgets/baseview_widget.gui" />
</defs>
</svg>

That should be pretty much all you need. Press the back button to display the exit confirmation screen and then tap either of the two displayed buttons, or click back / down physical buttons to cancel exiting or the top button to confirm exit.

 

 

Running PageRunning PageExit Confirmation PageExit Confirmation Page

 

View best answer in original post

Best Answer
10 REPLIES 10

You add events to physical buttons. You can add an onunload event with the AppBit API and save data there.

Best Answer
0 Votes

Thank you FredFitbit.

 

Is mapping the left button in the development plan? The right hand two are effectively mapped against the right hand combo buttons.

 

At the moment it is too easy to accidentally exit the application when you didn't actually mean to (mid run when you tap the button to wake up but accidentally hit it twice --- frustrating.

 

Some thought would need to be given to prevent malicious code from stopping a user exiting an application. A double tap on the left button for example ....

Best Answer
0 Votes

I think the answer for an app is described here: 

https://dev.fitbit.com/guides/user-interface/javascript/#using-the-physical-buttons

 

The document object emits keypress events when the user presses one of the physical buttons. Long press button events are reserved for system use only.

import document from "document";

document.onkeypress = function(e) {
  console.log("Key pressed: " + e.key);
}

The possible values for e.key are down, up, and back.

Best Answer

My bad, it's only long press that are reserved for the system, I updated my answer, thaks @qooApps .

Best Answer
0 Votes

Thank you qooApps for your reply and useful information - help like this from the community is genuinely appreciated.

 

This however doesn't solve the issue with accidentally closing the application.

 

Yes indeed you do get a 'back' event firing - which you can save data automatically.- but how can you then present a "Are You Sure?" with a Yes / No selection. 

 

Is this something that FitBit has in their development pathway?

Best Answer
0 Votes

You can prevent the default action of the back button (“exiting the app”) by using event.preventDefault() inside the onkeypressfunction but I’m not sure how to close the app programatically 

 

document.onkeypress = function(evt) {
   if (evt.key === "back") {

       evt.preventDefault();

       // display confirmation message 
   }
}

Best Answer

Thank you pautomas.

 

It would be good to know if there is a way to close the app programatically.

 

In the meantime it would be possible, when clicking the back button, to check whether the user has previously clicked and positively responded to a "are you sure message?" If they have then allow exit, otherwise evt.preventDefault() would be executed.

 

Clunky - but workable.

Best Answer
0 Votes

 

Just put together a little test to remap the "back" button to the "top" button.

 

So it is entirely possible to prevent accidental exit from the application.

 

Thanks to those who helped out on this Smiley Very Happy

 

import document from "document";
import { me } from "appbit";


document.onkeypress = function(e) {
  console.log("Key pressed: " + e.key);
  e.preventDefault();
    if (e.key==="up") {
      console.log("trapped");
      me.exit();
  }

 Have updated this post to show a full solution in the hope it helps someone out in the community:

 

app/index.js

 

import document from "document";
import { me } from "appbit";
import clock from "clock";

let runningPage = document.getElementById("runningPage");
let exitPage = document.getElementById("exitPage");
let timeDisplay = document.getElementById("time");
let dateDisplay = document.getElementById("date");
let btnyes = document.getElementById("btn-yes");
btnyes.onclick = function(evt) {
me.exit();
}
let btnno = document.getElementById("btn-no");
btnno.onclick = function(evt) {
runningPage.style.display="inline";
exitPage.style.display="none";
}

runningPage.style.display="inline";
exitPage.style.display="none";

document.onkeypress = function(e) {
e.preventDefault();
if (e.key=="up" && exitPage.style.display=="inline") {
me.exit();
}
if (e.key==="back" || e.key==="down") {
if (exitPage.style.display==="inline") {
runningPage.style.display="inline";
exitPage.style.display="none";
} else {
runningPage.style.display="none";
exitPage.style.display="inline";
}
}

}


clock.granularity = "seconds";
clock.ontick = () => showData();

function showData() {
let myDate=new Date();
let secs=zeroPad(myDate.getSeconds());
let mins=zeroPad(myDate.getMinutes());
let hrs=myDate.getHours();
let day=zeroPad(myDate.getDate());
let month=zeroPad(myDate.getMonth()+1);
let year=zeroPad(myDate.getFullYear());
timeDisplay.text=`${hrs}:${mins}:${secs}`;
dateDisplay.text=`${day}/${month}/${year}`;
}

function zeroPad(i) {
if (i < 10) {
i = "0" + i;
}
return i;
}

 

 

resources/index.gui

 

<svg> 
<svg id="runningPage">
<rect id="background2" pointer-events="none" />
<text y="110" x="50%" id="Title" font-family="System-Regular" fill="yellow" font-size="45" font-weight="bold" text-anchor="middle">Clock</text>
<text y="160" x="50%" id="time" font-family="System-Regular" fill="white" font-size="40" font-weight="bold" text-length="20" text-anchor="middle">Time: </text>
<text y="195" x="50%" id="date" font-family="System-Regular" fill="white" font-size="40" font-weight="bold" text-length="20" text-anchor="middle">Date: </text>
</svg>
<svg id="exitPage">
<text y="110" x="50%" id="Title" font-family="System-Regular" fill="yellow" font-size="45" font-weight="bold" text-anchor="middle">Exit: Are you sure?</text>
<svg y="$">
<use id="btn-yes" href="#square-button-toggle" x="50%" fill="fb-green">
<set href="#text" attributeName="text-buffer" to="Yes" />
</use>
<use id="btn-no" href="#square-button-toggle" value="1" fill="fb-red">
<set href="#text" attributeName="text-buffer" to="No" />
</use>
</svg>
</svg>
</svg>

 

 

resource/widgets.gui

 

<svg>
<defs>
<link rel="import" href="/mnt/sysassets/widgets_common.gui" />
<link rel="import" href="/mnt/sysassets/widgets/square_button_widget.gui" />
<link rel="import" href="/mnt/sysassets/widgets/baseview_widget.gui" />
</defs>
</svg>

That should be pretty much all you need. Press the back button to display the exit confirmation screen and then tap either of the two displayed buttons, or click back / down physical buttons to cancel exiting or the top button to confirm exit.

 

 

Running PageRunning PageExit Confirmation PageExit Confirmation Page

 

Best Answer

Moved content into the post above. Apologies for duplicating.

Best Answer
0 Votes

Thanks - helped me also.

Best Answer
0 Votes