I am making an iOS and Android app using Titanium Classic. I am fairly new to Titanium but I have some experience using Javascript. The app will have a window where the user and select from a picker an amount of time in hours and minutes. The selection will be saved and be used later to send a notification to the user that the time they selected is up. I am currently using Titanium's picker function with the type of "count down timer." However, I am having trouble getting the change event to work when the user selects a different time. It also will show the last selected time when I try going to a different window and entering the timer window again.
My question is how can I get the change event to fire the first time the user selects a different number?
In follow up to my question, is there a better way to save the picker selection for later use?
Here is the code for the picker:
var hours = 0;
var minutes = 1;
var win = Ti.UI.createWindow({
backgroundColor: '#A6B97B',
layout: 'horizontal'
});
var picker = Ti.UI.createPicker({
type:Ti.UI.PICKER_TYPE_COUNT_DOWN_TIMER,
top:2,
width: '50%',
height: '20%'
});
picker.addEventListener("change", function(e) {
Ti.App.Properties.setInt('countDownDuration', e.countDownDuration);
if (e.countDownDuration >= 3600000)
{
hours = Math.floor(Ti.App.Properties.getInt('countDownDuration')/3600000);
minutes = Math.floor(Ti.App.Properties.getInt('countDownDuration')/60000 - (hours*60));
}
else {
minutes = Math.floor(Ti.App.Properties.getInt('countDownDuration')/60000);
hours = 0;
}
});
var doneBtn = Ti.UI.createButton({
title : 'Get Value',
height : '15%',
width : '30%'
});
doneBtn.addEventListener('click', function() {
// get value
if(hours > 0){
alert('You set the time estimate to ' + hours + ' hours and ' + minutes+ ' minutes');
}
else {
alert('You set the time estimate to ' + minutes + ' minutes');
}
});
If anyone has any advice on how to get the change event to fire the first time, I would really appreciate it. Also, if you know a better way to accomplish saving data from the picker for use later, that would be helpful as well.
Thanks!
Jessica
Related
I am updating a Titanium mobile application which can schedule alarm notification for events, such that notification will pop up at the scheduled time.
Originally the mobile application is using a titanium module named as benCoding AlarmManager: https://github.com/benbahrenburg/benCoding.AlarmManager to schedule notification. However after I upgraded titanium SDK from 8.3.0 to 9.0.0, I found that there would be error starting the application if I killed the application before the notification scheduled time. For example, if I schedule an alarm notification at 8:00 and the application is not running in the background at 8:00. Although notification will pop up at 8:00, there will be error when starting the application.
E/TiExceptionHandler: (main) [333,333] <embedded>:19295
return originalRequire(moduleId);
^
TypeError: originalRequire is not a function
at global.require (<embedded>:19295:10)
at <embedded>:19555:3
at loadAsync (<embedded>:19481:5)
at _startSnapshot (<embedded>:19552:1)
at /ti.main.js:1:98
at Module._runScript (ti:/module.js:587:9)
at Module.load (ti:/module.js:106:7)
at Function.Module.runModule (ti:/module.js:74:9)
org.appcelerator.kroll.runtime.v8.V8Runtime.nativeRunModule(Native Method)
org.appcelerator.kroll.runtime.v8.V8Runtime.doRunModule(V8Runtime.java:174)
org.appcelerator.titanium.TiApplication.launch(TiApplication.java:791)
org.appcelerator.titanium.TiLaunchActivity.loadScript(TiLaunchActivity.java:98)
org.appcelerator.titanium.TiRootActivity.loadScript(TiRootActivity.java:480)
org.appcelerator.titanium.TiLaunchActivity.onResume(TiLaunchActivity.java:179)
org.appcelerator.titanium.TiRootActivity.onResume(TiRootActivity.java:499)
android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1446)
android.app.Activity.performResume(Activity.java:7939)
android.app.ActivityThread.performResumeActivity(ActivityThread.java:4195)
I included one of my example code on AlarmManager, which will schedule a notification after pressing a button. The notification will be pop up after 2 minutes and pressing the notification will create error message "originalRequire is not a function".
// this sets the background color of the master UIView (when there are no windows/tab groups on it)
Ti.UI.setBackgroundColor('#000');
// Add this in so Titanium will add the permission for us.
Titanium.Media.vibrate();
// Add this so Titanium will add the permissions and links needed to play sounds
var sound = Titanium.Media.createSound();
// Bring in the module
var alarmModule = require('bencoding.alarmmanager');
// Create a new instance of the Alarm Manager
var alarmManager = alarmModule.createAlarmManager();
// Create our basic window to put our example buttons on
var win = Titanium.UI.createWindow({
title:'Tab 1', backgroundColor:'#fff', title:'Alarm Manager Tests'
});
var btn1 = Ti.UI.createButton({
title:"Alarm & Notify Basic", top:10, left:5, width: 150, height:75
});
win.add(btn1);
btn1.addEventListener('click', function(e){
scheduleAlert = function(id, title, content) {
id = parseInt(id);
var date = new Date();
alarmManager.cancelAlarmService(id);
// To resolve the problem mutiple alarm at the same time using Android alarmanager
var dateStr = "alarm" + date.getTime();
Ti.API.info("addAlarmService:"+ date.getFullYear() + ", " + date.getMonth() + "," + date.getDate() + "," + date.getHours() + ","+date.getMinutes() + ", "+date.getSeconds());
var hr = date.getHours();
var min = date.getMinutes() + 2;
var sec = date.getSeconds();
alarmManager.addAlarmService({
service : Ti.App.id + '.AlertServiceService',
requestCode : id,
//icon: Ti.Android.R.drawable.star_on, //Optional icon must be a resource id or url
year : date.getFullYear(),
month : date.getMonth(),
day : date.getDate(),
hour : hr,
minute : min,
second : sec
});
var ew = Ti.UI.createAlertDialog({
title : 'Info',
message : "The Service provided will be started at " + hr + ":" + min + ":" + sec,
buttonNames : [Ti.Android.currentActivity.getString(Ti.Android.R.string.ok)]
});
ew.show();
};
scheduleAlert(1, "Testing 123", "");
});
win.open();
I know that benCoding AlarmManager is a bit old and the last updated date is Jan 2018, however I do not know what alternatives can I use to generate notification same as AlarmManager in a Titanium application. Grateful if someone could provide advice for me on the error above or provide some alternatives on AlarmManager. Thanks.
i want to make the notification push on like maybe 5 minute after i run this http function. delete the event_time from the jsaon of notification i will receive the push notification that have timeline now, but if i hard code the event_time the time will show 50 year ago since epoch time , event i put 999 for the year it just increase by 2 year . i dint get it at all. then found Timestapm format in google and firebase so use it and the android got error whil parsing the json payload said cant fine field something . have any idea to format the Zulu RC399 time format?
pp.get('/sendCloudMessageReminderActivation', async (req, res) => {
const x = req.query.userUID;
const xstr = String(x);
const zxcv = admin.firestore().collection('user').doc(xstr);
const xoxo = await zxcv.get();
var today = new Date();
// today.setHours(today.getHours()+1);
today.setHours(today.getHours()+8);
// today.setFullYear(today.getFullYear()+50);
var xoxocode;
console.log(today+'saya saya sebelum cagbge');
// today = ISODateString(today);
const timestamp = admin.firestore.Timestamp.fromDate(today);
console.log(timestamp.nanoseconds +'siniiiiiiiiiiiiiiiiiiiii');
if (xoxo!==null) {
xoxocode= await xoxo.data().cloudMessagingToken;
const message = {
notification: {
title: 'your account is still in active state',
body: 'Tap here to check it out!'
},
android:{
priority:'high',
// important : 'MAX',
notification:{
notification_priority: "PRIORITY_MAX",
event_time: timestamp,// when ever i cahnge this event use ZULU RC339 format i still give my 50 year ago notification. i did my research but cant figure out how to do this ,
default_sound: true,
// notification_priority: PRIORITY_MAX
}
},
token: xoxocode
};
// res.status(200).send('authorized');
const respondfrommesage = admin.messaging().send(message);
console.log(respondfrommesage);
res.status(200).send('message send notification');
}
res.end();
});
Zulu is not a time format. It's a time zone. Zulu is just another name for UTC.
As per this article:
Another name for UTC Time is "Zulu" or "Z Time."
Now, about the timestamp value. If you are creating a Date object and use milliseconds or nanoseconds property of a date, it will always give you the difference in respective property type (mills/nano),
From the time you created the instance and starting time of UNIX which is 1 January 1970.
It has been 50 years as of 1st Jan, 2020. Hence the 50 year difference in the event_time.
If you have any other doubts let me know.
I'm trying to implement the Phonegap local notification in my project.
I'm using this plugin:
de.appplant.cordova.plugin.local-notification-custom
I have installed the plugin and tested it and it works fine.
I tested it with this code and it works fine:
cordova.plugins.notification.local.schedule({
id : 1,
title : 'I will bother you every minute',
text : '.. until you cancel all notifications',
sound : null,
every : 'minute',
autoClear : false,
at : new Date(new Date().getTime() + 10*1000)
});
The above notification will run every minute and work fine.
Now, I need to set a local notification that will only run on every Sunday and every week.
I came across something like this but when tested it, it does nothing:
cordova.plugins.notification.local.schedule({
id: 1,
title: "Test...",
text: "Test...",
sound: null,
every: 'week',
at: sunday_16_pm
});
I don't even know if at: sunday_16_pm is correct or not!
Could someone please advice on this issue?
Thanks in advance.
EDIT:
After searching for hours and finding nothing, I just came across this documentation:
https://github.com/katzer/cordova-plugin-local-notifications/wiki/04.-Scheduling
They have a sample code that says:
Schedule Repeatedly
cordova.plugins.notification.local.schedule({
text: "Delayed Notification",
firstAt: monday,
every: "day",
icon: "file://img/logo.png"
}, callback);
But what is monday?!? is that a variable? And if so, how do you create that variable?
I don't understand why people write documentation as if no one else would want to read/understand them!!
Another edit:
I found this which explains exactly what i'm trying to do but I'm not using ionic and never have. So I don't understand the code that is provided there at all!
https://www.joshmorony.com/getting-familiar-with-local-notifications-in-ionic-2/
I don't know about those variables sunday_16_pm or monday either, but you can use your own variable with firstAt.
First of all you have to find the timestamp for sunday_16_pm to tell this plugin that the repeating should start on sunday afternoon.
In order to find this timestamp (that I suppose this should be done dynamically), I wrote the function getDayMillDiff to calculate the time-difference between now and sunday. Afterwards this difference is used to obtain the desired sunday_16_pm.
function getDayMillDiff(refday){
var days = {
monday: 1,
tuesday: 2,
wednesday: 3,
thursday: 4,
friday: 5,
saturday: 6,
sunday: 0
};
if(!days.hasOwnProperty(refday))throw new Error(refday+" is not listed in "+JSON.stringify(days));
var curr = new Date();
var triggerDay = days[refday];
var dayMillDiff=0;
var dayInMill = 1000*60*60*24;
// add a day as long as refday(sunday for instance) is not reached
while(curr.getDay()!=triggerDay){
dayMillDiff += dayInMill;
curr = new Date(curr.getTime()+dayInMill);
}
return dayMillDiff;
}
var today = new Date();
// how many days are between current day (thursday for instance) to sunday, add this difference to this sunday variable
var sunday = today.getTime() + getDayMillDiff("sunday");
// convert timestamp to Date so that hours can be adjusted
var sunday_16_pm = new Date(sunday);
sunday_16_pm.setHours(16,0,0);
// now we can use sunday_16_pm to schedule a notification showing at this date and every past week
cordova.plugins.notification.local.schedule({
id: 1,
title: "Test...",
text: "Test...",
every: 'week',
firstAt: sunday_16_pm
});
One more example:
To test getDayMillDiff for other days than sunday, you can simply pass the string "monday" onto it (please use always a name listed within the variable days in getDayMillDiff):
var today = new Date();
var monday = today.getTime() + getDayMillDiff("monday");
var monday_10_am = new Date(monday);
monday_10_am.setHours(10,0,0);
cordova.plugins.notification.local.schedule({
id: 1,
title: "Test...",
text: "Test...",
every: 'week',
firstAt: monday_10_am
});
Hope it helps.
I'd like to get the system-time inclusive the milliseconds. Therefore I use this method to get the system-time:
1)
var dt = JSON.stringify(new Date());
The dateToString method only returns the date-format with minutes, not the seoonds and milliseconds
2)
navigator.globalization.dateToString(
new Date(),
function (date) { alert('date: ' + date.value + '\n'); },
function () { alert('Error getting dateString\n'); },
{ formatLength: 'short', selector: 'date and time' }
);
My system-time is 13:07
returns
11:07:44...
returns
13:07
Is it possible to get the seconds and milliseconds from the dateToString method?
JavaScript's Date() has a lot of methods that can help you, like getMilliseconds() which will return....the number of milliseconds. There is also getMinutes, getSeconds, etc. See the full list here:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date
I have a problem where a drop-down select box does not drop-down (it's essentially inactive) when viewed on an Android mobile device. It works fine on desktop browsers as well as ios browser - bringing up a picker wheel on ios and a dropdown select list from the desktop.
Sample code is;
<select id = "log_or_norm" autofocus>
<option value="1">Lognormal</option>
<option value="2">Normal</option>
</select>
I tried the suggestion found at;
http://youngliferamblings.wordpress.com/2011/08/09/select-dropdown-in-android-webview/
which was
The select tag just doesn’t work sometimes in Android, especially in an app using webview. This drove me nuts for a long long time. The main fix I found, even if your select is buried deep in divs and rows and what ever, is this css:
select {
visibility: visible;
-webkit-appearance: menulist-text;
}
The -webkit-appearance might be the only one actually needed and setting it to ‘listbox’ works too.
That’s all. This deserved its own post.
Without luck....
Am hoping that one of the gurus here can provide an elegant solution that will avoid me having to go down the route of making discrete buttons for each option. I'm not fussed as to whether the Android experience gets a nice picker wheel or not, but need to be able to allow Android users to select an option.
Thanking you in advance
Try
getDriver().createElement(By.id("your locator"));
getDriver().createElement(By.id("your locator")).sendKeys("option Name you want to give");
var divCreated = false;
$(document).ready(function () {
var value = "";
$("select").each(function (i) {
$(this).click(function () {
//alert(($(this).is(":focus")));
if (!($(this).is(":focus"))) {
if (!divCreated) {
$("body").append('<div class="for_select"></div>');
divCreated = true;
}
$(this).clone().appendTo(".for_select");
open($(this));
}
});
});
function open(obj) {
var pos = $(obj).offset();
$(".for_select select").css("position", "absolute");
$(".for_select select").css("zIndex", "9999999999999");
var toAdd = $(obj).innerHeight();
$(".for_select select").offset({
top: pos.top + toAdd,
left: pos.left
});
$(".for_select select").attr("size", ($(obj).children("option").length > 10 ? 10 : $(obj).children("option").length));
$(".for_select select").change(function () {
value = $(".for_select select").val();
$(obj).val(value);
$(obj).children("option").each(function () {
if ($(this).text() == value)
$(this).attr("selected", "selected");
else if ($(this).attr("selected")) {
$(this).removeAttr("selected");
}
});
var parentHeight = $(obj).parent().innerHeight();
$(obj).parent().css("height", parentHeight + "px");
$(obj).parent().css("position", "relative");
$(obj).css("position", "absolute");
$(obj).css("left", "0px");
var prevElementsHeight = 0;
var isSelect = false;
$(obj).parent().children("*").each(function () {
if ($(this) == $(obj))
isSelect = true;
if (!isSelect)
prevElementsHeight += $(this).innerHeight();
});
$(obj).css("top", (prevElementsHeight / 2) + "px");
$(obj).css("zIndex", "9999");
close($(".for_select select"));
});
}
function close(obj) {
$(obj).css("position", "static");
$(obj).attr("size", "1");
$(".for_select").empty();
}
});
The solution came rather simple after I battled this for days.
Try debugging by bringing out the select from nested divs until you find the problematic div.
In my case, the problem was that I wrapped all the data-role="page" divs in a parent div (for loading sake on low-end devices). For some reason, < Android 2.3 has a problem with that.