I have this code in "index.js" file.
Communication takes place , show me thenotification , but how can I do to display the notification in the status bar when the app is closed ? Thanks for the help.
var pushNotification;
function onDeviceReady() {
$("#app-status-ul").append('<li>deviceready event received</li>');
document.addEventListener("backbutton", function(e)
{
$("#app-status-ul").append('<li>backbutton event received</li>');
if( $("#home").length > 0)
{
// call this to get a new token each time. don't call it to reuse existing token.
//pushNotification.unregister(successHandler, errorHandler);
e.preventDefault();
navigator.app.exitApp();
}
else
{
navigator.app.backHistory();
}
}, false);
try
{
pushNotification = window.plugins.pushNotification;
$("#app-status-ul").append('<li>registering ' + device.platform + '</li>');
if (device.platform == 'android' || device.platform == 'Android' || device.platform == 'amazon-fireos' ) {
pushNotification.register(successHandler, errorHandler, {"senderID":"615604299101","ecb":"onNotification"}); // required!
} else {
pushNotification.register(tokenHandler, errorHandler, {"badge":"true","sound":"true","alert":"true","ecb":"onNotificationAPN"}); // required!
}
}
catch(err)
{
txt="There was an error on this page.\n\n";
txt+="Error description: " + err.message + "\n\n";
alert(txt);
}
}
// handle GCM notifications for Android
function onNotification(e) {
$("#app-status-ul").append('<li>EVENT -> RECEIVED:' + e.event + '</li>');
switch( e.event )
{
case 'registered':
if ( e.regid.length > 0 )
{
$("#app-status-ul").append('<li>REGISTERED -> REGID:' + e.regid + "</li>");
// Your GCM push server needs to know the regID before it can push to this device
// here is where you might want to send it the regID for later use.
console.log("regID = " + e.regid);
}
break;
case 'message':
// if this flag is set, this notification happened while we were in the foreground.
// you might want to play a sound to get the user's attention, throw up a dialog, etc.
if (e.foreground)
{
$("#app-status-ul").append('<li>--INLINE NOTIFICATION--' + '</li>');
// on Android soundname is outside the payload.
// On Amazon FireOS all custom attributes are contained within payload
var soundfile = e.soundname || e.payload.sound;
// if the notification contains a soundname, play it.
// playing a sound also requires the org.apache.cordova.media plugin
var my_media = new Media("/android_asset/www/"+ soundfile);
my_media.play();
}
else
{ // otherwise we were launched because the user touched a notification in the notification tray.
if (e.coldstart)
$("#app-status-ul").append('<li>--COLDSTART NOTIFICATION--' + '</li>');
else
$("#app-status-ul").append('<li>--BACKGROUND NOTIFICATION--' + '</li>');
}
$("#app-status-ul").append('<li>MESSAGE -> MSG: ' + e.payload.message + '</li>');
//android only
$("#app-status-ul").append('<li>MESSAGE -> MSGCNT: ' + e.payload.msgcnt + '</li>');
//amazon-fireos only
$("#app-status-ul").append('<li>MESSAGE -> TIMESTAMP: ' + e.payload.timeStamp + '</li>');
break;
case 'error':
$("#app-status-ul").append('<li>ERROR -> MSG:' + e.msg + '</li>');
break;
default:
$("#app-status-ul").append('<li>EVENT -> Unknown, an event was received and we do not know what it is</li>');
break;
}
}
function tokenHandler (result) {
$("#app-status-ul").append('<li>token: '+ result +'</li>');
// Your iOS push server needs to know the token before it can push to this device
// here is where you might want to send it the token for later use.
}
function successHandler (result) {
$("#app-status-ul").append('<li>success:'+ result +'</li>');
}
function errorHandler (error) {
$("#app-status-ul").append('<li>error:'+ error +'</li>');
}
document.addEventListener('deviceready', onDeviceReady, true);
It should appear with this code. Are you sending the notification with message and title? If they are missing, the notification doesn't appears
The notification shows in the status bar when the app is closed or inactive
if (e.coldstart)
// Your code when the user clicks on the notification.
}
Related
I'm doing a project for University where I have a login for a website and I have to implement some operations. My issue is to maintain user session when a user is logged; so, if I open the website in a new tab, I want to be logged with the account of the main tab.
This is my angularjs code for the loginController:
mainAngularModule
.controller('LoginCtrl', ['$scope', '$state', 'AuthFactory',
function ($scope, $state, AuthFactory) {
let ctrl = this;
ctrl.authRequest = {username: 'admin', password: 'password'};
ctrl.doLogin = doLoginFn;
ctrl.authMessage = '';
//check if user already logged
let logSession = localStorage.getItem(("authinfo"));
if(logSession == null){
console.log("logSession null");
}
if(logSession == undefined){
console.log("isundefined");
}
if(logSession != null){
console.log("not null");
console.log("usern: " + logSession.username);
//console.log("authinfo authorities: " + logSession.authorities)
AuthFactory.setJWTAuthInfo(logSession);
$state.go("dashboard.home");
}
console.log("login authinfo: " + localStorage.getItem("authinfo"));
let sessionStorage_transfer = function(event) {
if(!event) { event = window.event; } // ie suq
if(!event.newValue) return; // do nothing if no value to work with
if (event.key === 'getSessionStorage') {
// another tab asked for the sessionStorage -> send it
localStorage.setItem('sessionStorage', JSON.stringify(sessionStorage));
// the other tab should now have it, so we're done with it.
} else if (event.key === 'sessionStorage' && !sessionStorage.length) {
// another tab sent data <- get it
var data = JSON.parse(event.newValue);
for (var key in data) {
sessionStorage.setItem(key, data[key]);
}
}
};
// listen for changes to localStorage
if(window.addEventListener) {
window.addEventListener("storage", sessionStorage_transfer, false);
} else {
window.attachEvent("onstorage", sessionStorage_transfer);
}
function doLoginFn() {
console.log("doLoginFn");
var requiresLogin = $state.jwtToken;
console.log("requireLogin: " + requiresLogin);
AuthFactory.sendLogin(ctrl.authRequest, successCB, errorCB);
function successCB(response) {
let authInfo = response.data;
console.log("data = " + response.data.all);
let header = response.headers();
authInfo.jwtToken = header['authorization'];
console.log("authInfo", authInfo);
// AuthFactory.user.username = authInfo.username;
// AuthFactory.user.role = authInfo.role;
let debugJWT = true;
//if (debugJWT) {
if (true) {
console.log(authInfo);
console.log("username: " + authInfo.username);
console.log("roles: " + JSON.stringify(authInfo.authorities));
console.log("jwtToken: " + authInfo.jwtToken);
console.log("userType: " + authInfo.userRole);
console.log("ended.");
}
AuthFactory.setJWTAuthInfo(authInfo);
//console.log("authinfoo1234: " + authInfo);
// localStorage.setItem("authinfo",authInfo);
console.log("authorities: " + authInfo.authorities);
$state.go("dashboard.home");
}
function errorCB(response) {
let error = response.data;
if (error && error.status === 401) {
ctrl.authMessage = error.message;
}
else {
console.error(response);
ctrl.authMessage = 'No response from server';
}
}
}
}
]);
I have a very strange problem: I'm using Intellj, and it tells me in lines
console.log("roles: " + JSON.stringify(authInfo.authorities));
console.log("userType: " + authInfo.userRole);
but if I comment lines with localStorage.setItem and localStorage.getItem, console prints on output correct userType and userRole; if I add those lines, console prints out this message:
TypeError
columnNumber: 17
fileName: "http://localhost:63342/ISSSR_frontend/app/scripts/service/AuthFactory.js"
lineNumber: 59
message: "authInfo.authorities is undefined"
I really don't understand, why it says me that it cannot resolve variable, but it can print out it?
Unfortunately I could not deploy your code would you please prepare codepen or flickr.
Some points that I can mention is below:
instead of use console.log("username: " + authInfo.username); use : console.log('username : ',authInfo.username)
Instead of JSON.stringify(authInfo.authorities) use : angular.toJson(authInfo.authorities,true)
Also console.log(response) to see what it returns.
This question is edit for better undersatnding:
I am trying to use the cordova fileOpener2 plugin to open pdf files in my app's assets.
I obtain the file's uri thanks to lines 14 and onward of code below.
The uri is then stored as a varialbe (nonencodeduri).
However when I try to use the variable in the second part of the code where FileOpener2 needs the path to the file (from line 58), it stalls.
This is surprising because if I write hardcode the path to the same file line 58 (var uri = var uri = encodeURI("path to file in the assets of the app"), it works.
Thanks for helping me resolve this.
Here is the full code (credits: Ghandi)
var entry, documentname, documentid, referenceID, callLogID, filePath, blob,cdr,fileObject;
var filename = "test.pdf";
$(document).ready(function() {
document.addEventListener("deviceready", onDeviceReady, false);
});
var fileURL = "";
var imagePath = "";
function onDeviceReady() {
sessionStorage.platform = device.platform;
var fileTransfer = new FileTransfer();
$('a[href$=\\.pdf]').click(function()
{
try {
alert('Hi boys');
var urinonencoded = this.href;
alert(urinonencoded + ' and voila');
if (sessionStorage.platform.toLowerCase() == "android") {
window.resolveLocalFileSystemURL(cordova.file.externalRootDirectory,onFileSystemSuccess, onError);
}
else {
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0,onFileSystemSuccess, onError);
}
}
catch(err) {
alert("ER - " + err.message);
}
});
function onError(e) {
alert("onError");
};
function onFileSystemSuccess(fileSystem) {
var entry="";
if (sessionStorage.platform.toLowerCase() == "android") {
entry=fileSystem;
}
else {
entry=fileSystem.root;
}
entry.getDirectory("Cordova", {create: true, exclusive: false}, onGetDirectorySuccess, onGetDirectoryFail);
};
function onGetDirectorySuccess(dir) {
dir.getDirectory("Sample_App", {create: true, exclusive: false}, onGetDirectorySuccess1, onGetDirectoryFail);
};
function onGetDirectorySuccess1(dir) {
cdr = dir;
dir.getFile(filename,{create:true, exclusive:false},gotFileEntry, errorHandler);
};
function gotFileEntry(fileEntry) {
/*var uri = encodeURI(myref);*/
var uri = urinonencoded;
alert (uri);
alert("dest - " + cdr.nativeURL+filename);
fileTransfer.download(uri,cdr.nativeURL+filename,
function(entry) {
openFile();
},
function(error) {
alert("download error source " + error.source);
alert("download error target " + error.target);
alert("upload error code" + error.code);
alert("error");
},
true);
};
function openFile() {
alert("URL - " + cdr.nativeURL+filename);
cordova.plugins.fileOpener2.open(
cdr.nativeURL+filename,
'application/pdf',
//'text/plain',
{
error : function(e) {
alert('Error status: ' + e.status + ' - Error message: ' + e.message);
},
success : function () {
}
}
);
};
function onFileSystemSuccessDelete(fileSystem) {
var entry="";
if (sessionStorage.platform.toLowerCase() == "android") {
entry=fileSystem;
}
else {
entry=fileSystem.root;
}
entry.getDirectory("Cordova/Sample_App", {create: true, exclusive: false}, onGetDirectorySuccessDelete, onGetDirectoryFail);
};
function onGetDirectorySuccessDelete(dir) {
dir.getFile(filename,{create: true, exclusive:false},gotFileEntryDelete, fail);
};
function gotFileEntryDelete(fileEntry) {
fileEntry.remove();
var uri = encodeURI("http://SERVER_IP:PORT/test.pdf");
fileTransfer.download(uri,cdr.nativeURL+filename,
function(entry) {
console.log("download complete: " + entry.toURL());
openFile();
},
function(error) {
alert("download error source " + error.source);
alert("download error target " + error.target);
alert("upload error code" + error.code);
alert("error");
},
true);
};
function fail(error){
alert("ec - " + error.code);
};
function errorHandler(e) {
var msg = '';
switch (e.code) {
case FileError.QUOTA_EXCEEDED_ERR:
msg = 'QUOTA_EXCEEDED_ERR';
break;
case FileError.NOT_FOUND_ERR:
msg = 'NOT_FOUND_ERR';
break;
case FileError.SECURITY_ERR:
msg = 'SECURITY_ERR';
break;
case FileError.INVALID_MODIFICATION_ERR:
msg = 'INVALID_MODIFICATION_ERR';
break;
case FileError.INVALID_STATE_ERR:
msg = 'INVALID_STATE_ERR';
break;
default:
msg = e.code;
break;
};
alert("Msg - " + msg);
};
function onGetDirectoryFail(error) {
alert("onGetDirectoryFail");
};
$('#delete').click(ClearDirectory);
function ClearDirectory() {
alert("delete");
if (sessionStorage.platform.toLowerCase() == "android") {
window.resolveLocalFileSystemURL(cordova.file.externalRootDirectory,onFileSystemDirSuccess, fail);
}
else {
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0,onFileSystemDirSuccess, fail);
}
}
function onFileSystemDirSuccess(fileSystem) {
var entry = "";
if (sessionStorage.platform.toLowerCase() == "android") {
entry=fileSystem;
}
else {
entry=fileSystem.root;
}
entry.getDirectory("Cordova",{create : true, exclusive : false},
function(entry) {
entry.removeRecursively(function() {
console.log("Remove Recursively Succeeded");
}, fail);
}, getDirFail);
}
function getDirFail(error){
alert("getDirFail - " + error.code);
};
}
I used:
<script>
$('a[href$=\\.pdf]').click(function() {
var myuri = this.href ;
alert(this.href);
/*alert just to make sure I got the right uri (which works fine)*/
cordova.plugins.fileOpener2.open(
'this.href', // You can also use a Cordova-style file uri: cdvfile://localhost/persistent/Download/starwars.pdf
'application/pdf',
{
error : function(e)
{
alert('Error status: ' + e.status + ' - Error message: ' + e.message);
},
success : function ()
{
alert('file opened successfully');
}
}
);
return false;
});
</script>
and it hangs (i have the plugin declared in the config.xml file and present in the assets.
Can you pinpoint my error(s)?
Many thanks
Basically the issue is with the way you pass the file path paramter you pass to fileopener's open function and nothing wrong with the plugin as such.
If you pass this object inside single quote like 'this.href', it will be treated as a plain string and that's the issue. So you can use the approach as Joerg suggested in his answer.
Do check out this basic working sample app that demonstrates Cordova file operations. It should help you get started.
'this.href' is wrong, try it this way:
$('a[href$=\\.pdf]').click(function () {
var myuri = this.href;
alert(this.href);
/*alert just to make sure I got the right uri (which works fine)*/
cordova.plugins.fileOpener2.open(
myuri, // You can also use a Cordova-style file uri: cdvfile://localhost/persistent/Download/starwars.pdf
'application/pdf',
{
error: function (e) {
alert('Error status: ' + e.status + ' - Error message: ' + e.message);
},
success: function () {
alert('file opened successfully');
}
}
);
return false;
});
To sum up the answers for this complex problem:
first: fileopener2 will not work on its own, it needs other plugins to fit the purpose of opening pdf files on android. The other plugins needed are mentioned in Gandhi's excellent demo app available here.
Second: it is esssentiel to use Gandhi's app.js file that combines the different calls to plugins.
Third there are a number of functions involved in that file. In it the path is hard-coded, so everything seems to work well. But if you must use a dynamic path, then it must be stated globally (in other words, do not use "var" but simply myvar = this.href.
Although I found the last bits on my own, all the credit goes to Gandhi's excellent demo app which is a treasure trove for new plugin users he made available on github. +1 :-)
I am working on ionic project where i have to implement push notification
but practically what to do i have no idea
again my app is going to be used in corporate environment
so what to do .
Kindly suggest.
Hello Rigel,
Then first of all you have to install FOUR Plugins for that.
1)cordova plugin add https://github.com/phonegap-build/PushPlugin
// For notification
2)cordova plugin add cordova-plugin-device
// For on Device Ready to call
3)cordova plugin add cordova-plugin-dialogs
// For notification Dialog
4)cordova plugin add cordova-plugin-media
// For Notification Sound
and generate API key and SenderId throw developer console.and senderid past in bellow code. And e.regid pass to on server.
<script type="text/javascript" src="PushNotification.js"></script>
<script type="text/javascript">
var pushNotification;
function onDeviceReady() {
$("#app-status-ul").append('<li>deviceready event received</li>');
document.addEventListener("backbutton", function(e)
{
$("#app-status-ul").append('<li>backbutton event received</li>');
if( $("#home").length > 0)
{
// call this to get a new token each time. don't call it to reuse existing token.
//pushNotification.unregister(successHandler, errorHandler);
e.preventDefault();
navigator.app.exitApp();
}
else
{
navigator.app.backHistory();
}
}, false);
try
{
pushNotification = window.plugins.pushNotification;
$("#app-status-ul").append('<li>registering ' + device.platform + '</li>');
if (device.platform == 'android' || device.platform == 'Android' ||
device.platform == 'amazon-fireos' ) {
pushNotification.register(successHandler, errorHandler, {"senderID":"661780372179","ecb":"onNotification"}); // required!
} else {
pushNotification.register(tokenHandler, errorHandler, {"badge":"true","sound":"true","alert":"true","ecb":"onNotificationAPN"}); // required!
}
}
catch(err)
{
txt="There was an error on this page.\n\n";
txt+="Error description: " + err.message + "\n\n";
alert(txt);
}
}
// handle APNS notifications for iOS
function onNotificationAPN(e) {
if (e.alert) {
$("#app-status-ul").append('<li>push-notification: ' + e.alert + '</li>');
// showing an alert also requires the org.apache.cordova.dialogs plugin
navigator.notification.alert(e.alert);
}
if (e.sound) {
// playing a sound also requires the org.apache.cordova.media plugin
var snd = new Media(e.sound);
snd.play();
}
if (e.badge) {
pushNotification.setApplicationIconBadgeNumber(successHandler, e.badge);
}
}
// handle GCM notifications for Android
function onNotification(e) {
$("#app-status-ul").append('<li>EVENT -> RECEIVED:' + e.event + '</li>');
switch( e.event )
{
case 'registered':
if ( e.regid.length > 0 )
{
$("#app-status-ul").append('<li>REGISTERED -> REGID:' + e.regid + "</li>");
// Your GCM push server needs to know the regID before it can push to this device
// here is where you might want to send it the regID for later use.
console.log("regID = " + e.regid);
}
break;
case 'message':
// if this flag is set, this notification happened while we were in the foreground.
// you might want to play a sound to get the user's attention, throw up a dialog, etc.
if (e.foreground)
{
$("#app-status-ul").append('<li>--INLINE NOTIFICATION--' + '</li>');
// on Android soundname is outside the payload.
// On Amazon FireOS all custom attributes are contained within payload
var soundfile = e.soundname || e.payload.sound;
// if the notification contains a soundname, play it.
// playing a sound also requires the org.apache.cordova.media plugin
var my_media = new Media("/android_asset/www/"+ soundfile);
my_media.play();
}
else
{ // otherwise we were launched because the user touched a notification in the notification tray.
if (e.coldstart)
$("#app-status-ul").append('<li>--COLDSTART NOTIFICATION--' + '</li>');
else
$("#app-status-ul").append('<li>--BACKGROUND NOTIFICATION--' + '</li>');
}
$("#app-status-ul").append('<li>MESSAGE -> MSG: ' + e.payload.message + '</li>');
//android only
$("#app-status-ul").append('<li>MESSAGE -> MSGCNT: ' + e.payload.msgcnt + '</li>');
//amazon-fireos only
$("#app-status-ul").append('<li>MESSAGE -> TIMESTAMP: ' + e.payload.timeStamp + '</li>');
break;
case 'error':
$("#app-status-ul").append('<li>ERROR -> MSG:' + e.msg + '</li>');
break;
default:
$("#app-status-ul").append('<li>EVENT -> Unknown, an event was received and we do not know what it is</li>');
break;
}
}
function tokenHandler (result) {
$("#app-status-ul").append('<li>token: '+ result +'</li>');
// Your iOS push server needs to know the token before it can push to this device
// here is where you might want to send it the token for later use.
}
function successHandler (result) {
$("#app-status-ul").append('<li>success:'+ result +'</li>');
}
function errorHandler (error) {
$("#app-status-ul").append('<li>error:'+ error +'</li>');
}
document.addEventListener('deviceready', onDeviceReady, true);
</script>
<div id="home">
<div id="app-status-div">
<ul id="app-status-ul">
<li>Cordova PushNotification Plugin Demo</li>
</ul>
</div>
</div>
How to POST your registered token(e.regid) on server are bellow.
and important note your e.regid it's know as GCM ID.
if ( e.regid.length > 0 )
{
var userId = localStorage.getItem('userId');
$.ajax({
type: "POST",
url: '' + globURL + 'addgcm.php?user_id='+userId+'&gcm_id='+e.regid+'',
cache: false,
success: function(result){
}
});
// alert(regid);
$("#app-status-ul").append('<li>REGISTERED -> REGID:' + e.regid + "</li>");
// Your GCM push server needs to know the regID before it can push to this device
// here is where you might want to send it the regID for later use.
console.log("regID = " + e.regid);
}
I am trying to show the conversation between the two users even after the users logout and login. I mean when user1 logged out and again logged in, he should see the conversations made with the user2. I am using Ejabberd XMPP server and Strophe Js to retrive the messages.
As I found this strophe.mam.js plugin to do this but raising the error and cant get the messages.
Here is my code:
function onConnect(status)
{
// Functions runs while users trys to login to the XMPP server
var iq = null;
switch (status)
{
case Strophe.Status.CONNECTING:
log('Connecting.');
break;
case Strophe.Status.CONNFAIL:
log('Failed to connect.');
$('#connect').get(0).value = 'connect';
break;
case Strophe.Status.DISCONNECTING:
log('Disconnecting.');
break;
case Strophe.Status.DISCONNECTED:
log('Disconnected.');
$('#connect').get(0).value = 'connect';
break;
case Strophe.Status.CONNECTED:
log('Connected.');
connection.addHandler(onMessage, null, 'message', null, null, null);
connection.addHandler(onPresence, null, 'presence', null, null, null);
iq = $iq({type: 'get'}).c('query', {xmlns: 'jabber:iq:roster'});
connection.sendIQ(iq, onRoster);
break;
default:
break;
}
}
function onMessage(msg) {
debugger;
var fromJid = msg.getAttribute("from"),
bareFromJid = Strophe.getBareJidFromJid(fromJid),
type = msg.getAttribute("type"),
elems = msg.getElementsByTagName("body");
if (type == "chat" && elems.length > 0) {
var body = elems[0],
message = Strophe.getText(body);
showMessage(bareFromJid + ": " + message);
connection.mam.query("yashwanth#localhost", {
"with": bareFromJid,
onMessage: function(message) {
console.log("Message from " + bareFromJid,
": " + message);
return true;
},
onComplete: function(response) {
console.log("Got all the messages");
}
});
}
return true;
}
function send() {
// Handles with sending the message
var to = $('#to-jid').get(0).value,
myBareJid = Strophe.getBareJidFromJid(connection.jid);
message = $('#message').get(0).value,
reply = $msg({to: to, type: 'chat'})
.c("body")
.t(message);
connection.send(reply.tree());
showMessage(myBareJid + ": " + message);
}
$(document).ready(function () {
connection = new Strophe.Connection(BOSH_SERVICE);
messagebox = $("#messages");
messagebox.val("");
logbox = $("#log-messages");
logbox.val("");
rosterbox = $("#roster");
rosterbox.val("");
connection.rawInput = function (data) { log('RECV: ' + data); };
connection.rawOutput = function (data) { log('SEND: ' + data); };
Strophe.log = function (level, msg) { log('LOG: ' + msg); };
login();
$('#send').bind('click', send);
});
So whenever the user receives the message there will be something in the console. But it returns me this error in my logs
RECV: <body xmlns='http://jabber.org/protocol/httpbind'><iq xmlns='jabber:client'
from='yashwanth#localhost' to='yashwanth#localhost/22064184271436881211352579'
id='yashwanth#localhost' type='error'><query xmlns='urn:xmpp:mam:0'><x xmlns='jabber:x:data'><field
var='FORM_TYPE'><value>urn:xmpp:mam:0</value></field><field var='with'>
<value>shabda#localhost</value></field></x><set xmlns='http://jabber.org/protocol/rsm'/></query>
<error code='400' type='modify'><bad-request xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/></error>
</iq></body>
Please help me out with this
Your MAM query is not correctly formatted.
You are missing the attribute type="submit" on the x element with xmlns jabber:x:data feature. Type is mandatory in XEP-0004 Data Forms
You IQ should be:
<iq type='set' id='juliet1'>
<query xmlns='urn:xmpp:mam:0'>
<x xmlns='jabber:x:data' type='submit'>
<field var='FORM_TYPE' type='hidden'>
<value>urn:xmpp:mam:0</value>
</field>
<field var='with'>
<value>shabda#localhost</value>
</field>
</x>
<set xmlns='http://jabber.org/protocol/rsm'/>
</query>
</iq>
See Example 6 in XEP-0313 Message Archive Management.
The MAM strophe plugin had a bug. We prepared a fix here: https://github.com/processone/strophejs-plugins/commit/5a7857e2ab625c0521c68719d7e220f00c32c593
And submitted this pull request: https://github.com/strophe/strophejs-plugins/pull/65
I had a problem with MAM. See this link: https://www.ejabberd.im/forum/25028/solved-how-configure-and-test-modmam-message-archive-management
I solved the problem change type 'set' to 'get'
I have an MVC4 Web API application where i have my Api Controller and Code-First EF5 database and some JavaScript functions for the functionality of my app including my Ajax Calls for my Web Api Service.I did the project on MVC because i was having trouble installing Cordova in VS2012, so i have decided to use Eclipse/Android Phonegap platform.Is there a way where i can call my web api service and be able to retrieve my database data designed EF5(MVC4) in my Android Phonegap application without having to start from the beginning the same thing again.I know phonegap is basically Html(JavaScript and Css) but i am having trouble calling my service using the same HTML markup that i used MVC4.I am a beginner please let me know if what i am doing is possible and if not please do show me the light of how i can go about this. T*his is my Html code*
<script type="text/javascript" charset="utf-8" src="phonegap-2.9.0.js"></script>
<script type="text/javascript" charset="utf-8" src="barcodescanner.js"></script>
<script type="text/javascript" language="javascript" src="http://api.afrigis.co.za/loadjsapi/?key=...&version=2.6">
</script>
<script type="text/javascript" language="javascript">
// Wait for device API libraries to load
//
document.addEventListener("deviceready", onDeviceReady, false);
//initialize watchID Variable
var watchID = null;
// device APIs are available
function onDeviceReady() {
// Throw an error if no update is received every 30 seconds
var options = { timeout: 30000 };
watchID = navigator.geolocation.watchPosition(onSuccess, onError, options);
// onSuccess Geolocation
//
function onSuccess(position) {
var element = document.getElementById('geolocation');
element.innerHTML = 'Latitude: ' + position.coords.latitude + '<br />' +
'Longitude: ' + position.coords.longitude + '<br />' +
'<hr />' + element.innerHTML;
}
// onError Callback receives a PositionError object
//
function onError(error) {
alert('code: ' + error.code + '\n' +
'message: ' + error.message + '\n');
}
}
//declare a global map object
var agmap = null;
// declare zoom control of map
var zoomCtrl = null;
function initAGMap() {
agmap = new AGMap(document.getElementById("MapPanel"));
//TODO: must retrieve coords by device location not hard corded.
agmap.centreAndScale(new AGCoord(-25.7482681540537, 28.225935184269), 5); // zoom level 5 heres
// making zoom controls for map
var ctrlPos = new AGControlPosition(new AGPoint(10, 10), AGAnchor.TOP_LEFT);
zoomCtrl = new AGZoomControl(1);
agmap.addControl(zoomCtrl, ctrlPos);
}
function removeZoomCtrl()
{
zoomCtrl.remove();
}
//function search() {
// var lat = $('#latitude').val();
// var long = $('#longitude').val();
// $.ajax({
// url: "api/Attractions/?longitude=" + long + "&latitude=" + lat,
// type: "GET",
// success: function (data) {
// if (data == null) {
// $('#attractionName').html("No attractions to search");
// }
// else {
// $('#attractionName').html("You should visit " + data.Name);
// displayMap(data.Location.Geography.WellKnownText, data.Name);
// }
// }
// });
//}
//function GetCoordinate() {
//todo: get details from cordova, currently mocking up results
//return { latitude: -25.5, longitude: 28.5 };
}
function ShowCoordinate(coords) {
agmap.centreAndScale(new AGCoord(coords.latitude, coords.longitude), 5); // zoom level 5 here
var coord = new AGCoord(coords.latitude, coords.longitude);
var oMarker = new AGMarker(coord);
agmap.addOverlay(oMarker);
oMarker.show();
//todo: create a list of places found and display with marker on AfriGIS Map.
}
function ScanProduct()
{
//todo retrieve id from cordova as mockup
//This is mockup barcode
//return "1234";
//sample code using cordova barcodescanner plugin
var scanner = cordova.require("cordova/plugin/BarcodeScanner");
scanner.scan(
function (result) {
alert("We got a barcode\n" +
"Result: " + result.text + "\n" +
"Format: " + result.format + "\n" +
"Cancelled: " + result.cancelled);
},
//Callback function if barcodedont exist
function (error) {
alert("Scanning failed: " + error);
});
}
//Function to display Success or error in encoding.
function encode(type, data) {
window.plugins.barcodeScanner.encode(type, data, function(result) {
alert("encode success: " + result);
}, function(error) {
alert("encoding failed: " + error);
});}
function GetProductDetails(barcodeId,coords)
{
//Ajax Call to my web Api service
$.getJSON("api/products/?barcodeId=" + barcodeId + "&latitude=" + coords.latitude + "&longitude=" + coords.longitude)
.done(function (data) {
$('#result').append(data.message)
console.log(data)
var list = $("#result").append('<ul></ul>').find('ul');
$.each(data.results, function (i, item)
{
if (data.results == null) {
$('#result').append(data.message)
}
else {
list.append('<li>ShopName :' + item.retailerName + '</li>');
list.append('<li>Name : ' + item.productName + '</li>');
list.append('<li>Rand :' + item.price + '</li>');
list.append('<li>Distance in Km :' + item.Distance + '</li>');
//Another Solution
//var ul = $("<ul></ul>")
//ul.append("<li> Rand" + data.results.productName + "</li>");
//ul.append("<li> Rand" + data.results.Retailer.Name + "</li>");
//ul.append("<li> Rand" + data.results.price + "</li>");
//ul.append("<li> Rand" + data.results.Distance + "</li>");
//$("#result").append(ul);
}
});
$("#result").append(ul);
});
}
function ShowProductDetails()
{
//todo: display product details
//return productdetails.barcodeId + productdetails.retailerName + ': R' + productdetails.Price + productdetails.Distance;
}
//loading javascript api
$(function () {
initAGMap();
var coord = GetCoordinate();
ShowCoordinate(coord);
var barcodeId = ScanProduct();
var productdetails = GetProductDetails(barcodeId, coord);
ShowProductDetails(productdetails);
});
</script>
It looks like you're on the right track. The obvious error right now is that it's using a relative URL (api/products/?barcodeId=) to call the Web API. Because the HTML is no longer hosted on the same server as the Web API (even though you might be running them both on your local machine still), this won't work anymore. You need to call the service with an absolute URL (for example, http://localhost:8888/api/products/?barcodeId=).
Where is your Web API hosted right now and how are you running the Cordova code? If the Web API is up and running on your local machine and your Cordova app is running on an emulator on the same machine, you should be able to call the service by supplying its full localhost path.
If it still doesn't work, you'll need to somehow debug the code and see what the errors are.