i`m using apache cordova to build ios applications from some html, css and js. At this time i need to open other application inside opened application, for this purposes i use startapp plugin. Everything is ok, but i want opening itunes window inside app with link on application that need to open if application not installed. Here is function that i wrote, but it not give me the result that i want:
function appToApp(identifier, iTunesUrl, success, fail) {
var app;
// Init app starter
if(device.platform === 'iOS') {
app = startApp.set(identifier);
} else if(device.platform === 'Android') {
app = startApp.set({
"package": identifier
});
}
console.log('Checking ' + identifier + ' application existence...');
app.check(function(values) {
console.log('ok, application installed!');
console.log(values);
// Run application
console.log('Running ' + identifier + ' application...');
// Start application
app.start(function() {
console.log('App with identifier = ' + identifier + ' opened!');
if (typeof(success) == 'function') {
success.call();
}
}, function(error) {
console.log('Can not open app with identifier = ' + identifier + '!');
if (typeof(fail) == 'function') {
fail.call();
}
console.warn(error);
});
}, function(error) {
console.warn('Something wrong with application, checking failed!');
// Open iTunes
var iTunes = startApp.set('itunes://');
iTunes.start(function() {
console.log('iTunes opened!');
}, function(error) {
console.warn('Can not open iTunes!');
});
console.warn(error);
});
}
Thanks in advance
As a result i have used this cordova plugins Custom-URL-scheme, AppAvailability.
First of all i attached custom scheme to app that need launch form another app:
cordova plugin add cordova-plugin-customurlscheme --variable URL_SCHEME=mycoolapp
Function that open app:
/**
* Run app from other app
* Dependencies:
* https://github.com/EddyVerbruggen/Custom-URL-scheme
* https://github.com/ohh2ahh/AppAvailability
*
* #param {string} scheme - scheme part of url
* #param {string} url - custom application url
* #param {string} iTunesUrl - url on application that located on iTunes
*/
function appToApp(scheme, url, iTunesUrl) {
appAvailability.check(
// URI Scheme or Package Name
scheme,
function() {
// Success callback
console.log(scheme + ' is available :)');
// Open application
window.open(url, '_system');
},
function() {
// Error callback
console.log(scheme + ' is not available :(');
if (iTunesUrl) {
console.log('Installing app from iTunes');
window.open(iTunesUrl, '_system');
} else {
alert("Application " + scheme + " is not available on this device, please install application first");
}
}
);
}
Related
I made an application using twilio, webRTC and ionic, and the video call is working. However, is it possible to make the video call when the app runs in background? I couldn't come up with a solution with ionic.
I created a landing page upon login which has all the token grant and initialization of twilio so that once a user logs in. It is already on listening mode. Then, i handled the opening of push to actually just redirect to that particular landing page. In my case, the landing page is app.onlineUsers
var notificationOpenedCallback = function(jsonData) {
console.log('notificationOpenedCallback: ' + JSON.stringify(jsonData.action));
if (jsonData.action) {
if (jsonData.action.actionID == "IdAccept") {
$state.go('app.onlineUsers');
//custom code executes
} else if (jsonData.action.actionID == "IdReject") {
alert('rejected');
}
}
};
window.plugins.OneSignal.getIds(function(ids) {
// alert(ids);
did = ids.userId;
$sessionStorage.DID = did;
$localStorage.DID = did;
// alert(" player_id: "+$localStorage.DID);
});
// TODO: Update with your OneSignal AppId and googleProjectNumber before running.
window.plugins.OneSignal.startInit("appId", "googleProjectNumber")
.handleNotificationOpened(notificationOpenedCallback).handleNotificationReceived(function(jsonData) {
$state.go('app.onlineUsers');
// alert("Notification received:\n" + JSON.stringify(jsonData));
// console.log('Did I receive a notification: ' + JSON.stringify(jsonData));
}).inFocusDisplaying(window.plugins.OneSignal.OSInFocusDisplayOption.None).endInit();
In my application the following console error occurs when I navigate to another page.
Uncaught Error: SignalR: Connection has not been fully initialized. Use .start().done() or .start().fail() to run logic after the connection has started.
In layout page the scripts are in the following order.
#Styles.Render("~/Content/themes/base/jqueryUi")
#Styles.Render("~/Content/customCss")
#Scripts.Render("~/Scripts/jQuery")
#Scripts.Render("~/Scripts/customScripts")
<script src="/signalr/hubs"></script>
var progressHub = $.connection.parallelProcessing;
var flagDownload = true;
$(function() {
progressHub.client.updateProgresssBar = function(progressPercentage, downloadedSize, totalFileSize) {
debugger
downloadProgress("", "", "");
$("#downloading-progress").dialog("open");
var progressObj = $("#progressBar").data("ejProgressBar");
progressObj.option("text", progressPercentage + " %");
progressObj.option("percentage", progressPercentage);
$(".received").html("(" + downloadedSize + " ");
$(".total-size").html("of " + totalFileSize + ")");
flagDownload = true;
if (progressPercentage == 100)
$("#downloading-progress").dialog("close");
};
progressHub.client.noNetConnection = function() {
if (flagDownload) {
flagDownload = false;
showalertdownload("#Message.Nointernetconnection");
}
};
progressHub.client.closeProgressDialog = function() {
$("#downloading-progress").dialog("close");
enableEvents();
};
$.connection.hub.start().done(function () {
});
});
function updateConnectionID() {
progressHub.server.updateConnectionID();
}
Please let me know is ther any solution to resolve this issue.Thanks in advance.
Basing my answer on your error message, it seems you are trying to access your connection or hub without waiting for it to be initialized.
Taken from the ASP.NET SignalR Github wiki:
// This callback will only run once
connection.start().done(function() {
console.log("connection started!");
});
A more complete and detailed example to be found on ASP.NET website
I am working on an Android app using cordova and implemented a push notification system using the cordova $PushPlugin.
My PushPlugin code (source):
module.run(function($rootScope,$cordovaPush) {
var androidConfig = {
"senderID": "replace_with_sender_id",
};
document.addEventListener("deviceready", function(){
$cordovaPush.register(androidConfig).then(function(result) {
// Success
}, function(err) {
// Error
})
$rootScope.$on('$cordovaPush:notificationReceived', function(event, notification) {
switch(notification.event) {
case 'registered':
if (notification.regid.length > 0 ) {
alert('registration ID = ' + notification.regid);
}
break;
case 'message':
// this is the actual push notification. its format depends on the data model from the push server
alert('message = ' + notification.message + ' msgCount = ' + notification.msgcnt);
break;
case 'error':
alert('GCM error = ' + notification.msg);
break;
default:
alert('An unknown GCM event has occurred');
break;
}
});
// WARNING: dangerous to unregister (results in loss of tokenID)
$cordovaPush.unregister(options).then(function(result) {
// Success!
}, function(err) {
// Error
})
}, false);
});
On clicking the push notification received, I want to redirect the user to a specified page in my app. I referred this(based on phonegap pushplugin) but could not figure out a solution. Any help will be appreciated.
This is a simple solution without using any angular routes.
case 'message':
if (notification.foreground === false){
window.location = '#/abc';
window.location.reload();
}
If you check structure of object notification, you will see that there is an attribute foreground, which will be false when you come to app from clicking notification. You can use that to put your logic
case 'message':
if(notification.foreground === false){
//add logic for navigation to your specific page i.e $state.go('myPage')
}
I am doing pushnotification for both Android/IOS.
I have used a cordova push-plugin https://github.com/phonegap-build/PushPlugin, it seems to work great.
Info : I'm on a AngularJS project.
In my NotificationHelper factory i have this init method:
helper.init = function() {
// Instanciate push plugin notification
var pushNotification = window.plugins.pushNotification;
var errorHandler = function(error) {
logger.debug('errorHandler = ' + error);
};
if ($rootScope.isAndroid()) {
var senderId = CONFIG.NOTIFICATION_ANDROID_SENDER_ID;
pushNotification.register(function(result) {
logger.debug('successHandler = ' + result);
}, errorHandler, {
'senderID' : senderId,
'ecb' : 'onNotificationGCM'
});
}
};
I also defined those methods on mains.js :
var onNotificationGCM = function(event) {
// call back to web service in Angular.
var elem = angular.element(document.querySelector('[ng-app]'));
var injector = elem.injector();
var service = injector.get('NotificationHelper');
service.onNotificationGCM(event);
};
It's a trick to call angularJS factory from main javascript.
'onNotificationGCM' call the 'NotificationHelper.onNotificationGCM' method :
helper.onNotificationGCM = function(e) {
switch (e.event) {
case 'message':
// Notification happened while app was in the foreground
if (e.foreground) {
logger.debug('[notification] [message] Foreground : ' + JSON.stringify(e));
} else { // Notification touched in the notification tray
logger.debug('[notification] [message] Background : ' + JSON.stringify(e));
if (e.coldstart) {
// App was not running and user clicked on notification
} else {
// App was running and user clicked on notification
}
}
decriptPayloadNotification(e.payload);
break;
case 'registered':
logger.debug('[notification] [registered] : ' + JSON.stringify(e));
if (e.regid.length > 0) {
registerUser(e.regid, 'gcm');
}
break;
case 'error':
logger.debug('[notification] [error] : ' + JSON.stringify(e));
break;
default:
logger.debug('[notification] [default] : Unknown, an event was received and we do not know what it is : ' + JSON.stringify(e));
break;
}
};
During the first use, everything work good :
'Registered' event is received
Notifications are received
When i'm on foreground I receive 'message' event :
NotificationHelper: [notification] [message] Foreground : {"event":"message","from":"847593779913","message":"Agenêts 23/03 10h\r\n","collapse_key":"do_not_collapse","foreground":true,"payload":{"lt":"school","lv":"E1154","notId":"35429","title":"Agenêts le 23/03/2015","message":"Agenêts 23/03 10h\r\n"}}
When i'm on background, if i receive notif and touche it on notification tray, I receive 'message' event :
NotificationHelper: [notification] [message] Background : {"event":"message","from":"847593779913","message":"la piscine sera fermée 1 journée pour raison technique","coldstart":false,"collapse_key":"do_not_collapse","foreground":false,"payload":{"lt":"swimming pool","lv":"E114","notId":"29869","title":"23/04/2015 fermeture de la piscine","message":"la piscine sera fermée 1 journée pour raison technique"}}
BUT, if i kill my app, everything stop to work.
If i restart app, i will not receive anymore 'message'event and 'onNotificationGCM' will not be called.
I founded some articles speaking about this problem, but without success :
Stackoverflow : Phonegap PushNotification to open a specific app page
Does anyone has an idea about this problem ?
If you are using node-gcm as push notification server side I hope this might help for your question:
things to check:
use adb logcat from console and check your device logs to see if your device receives any notification (you should see some logs from gcmservices if you receive). I believe you should see some logs because otherwise you probably wouldn't get any notification when the app is on foreground either.
check if you add "title" and "message" keys on your message data (this draw me crazy before)
check if delayWhileIdle parameter is false
sample message variable and method i am using is below:
var pushAndroidSender = new gcm.Sender('Your GoogleApi Server Key Here');
var message = new gcm.Message({
collapseKey: 'demo',
delayWhileIdle: false,
timeToLive: 3,
data: {
"message":"What's up honey?",
"title":"Come on"
}
});
pushAndroidSender.send(message, registrationIds, function(err, result) {
if (err) {
console.error("this is an error: " + err);
} else {
console.log("this is a successful result:" + result);
}
});
I was asking myself why it worked correctly the first time and not the following times...and i had this idea :
maybe callback function is subscribed to plugin first time but not the next times.
And this is exactly the source of my problem. I call "pushNotification.register" only one time to init plugin and get ids...
But the next time I launch app, i don't instanciate again the plugin, so pushplugin don't know which method to call in callback request.
So answer is : Call "pushNotification.register" in each application launch !
In my code, i have to call method below on each "deviceready" event :
helper.init = function() {
// Instanciate push plugin notification
var pushNotification = window.plugins.pushNotification;
var errorHandler = function(error) {
logger.debug('errorHandler = ' + error);
};
if ($rootScope.isAndroid()) {
var senderId = CONFIG.NOTIFICATION_ANDROID_SENDER_ID;
pushNotification.register(function(result) {
logger.debug('successHandler = ' + result);
}, errorHandler, {
'senderID' : senderId,
'ecb' : 'onNotificationGCM'
});
}
};
I'm having a tough time getting push notifications (using the ngCordova plugin) to work. I have followed their sample code exactly as is documented on the site: http://ngcordova.com/docs/plugins/pushNotifications/
(the only difference is that I don't have a deviceready listener, instead, my code is inside the ionicPlatform.ready listener.)
Here is my code:
angular.module('myApp', ['ionic', 'ngCordova'])
.run(function($ionicPlatform, $rootScope, $state, $cordovaPush) {
$ionicPlatform.ready(function() {
var config = {
"senderID": "myID100001000"
};
$cordovaPush.register(config).then(function(result) {
alert(result);
}, function(err) {
alert(err);
})
});
$rootScope.$on('$cordovaPush:notificationReceived', function(event, notification) {
switch(notification.event) {
case 'registered':
if (notification.regid.length > 0 ) {
alert('registration ID = ' + notification.regid);
}
break;
default:
alert('An unknown GCM event has occurred');
break;
}
});
})
When my app starts I do get the "OK" alert, so I know it successfully goes through the $cordovaPush.register call. However, I was expecting to get a "registered" notification event, right after, but I never get notified.
Any help would be appreciated.
The solution is in the comments but this needs a proper answer.
First of all, the register callback always returns OK as long as you pass a senderID, but if the $cordovaPush:notificationReceived event is never called (it may take a few seconds), this ID is probably wrong.
You must use the Project Number, not the Project ID.
To get the number, go to the API Console, select the project and you'll be on the Overview page. On top of this page, you'll see something like this:
Project ID: your-project-id Project Number: 0123456789
Just copy and use the project number and everything should work.
I have suffered with this a lot and I have found out, that there are in fact two versions of the cordova push plugin currently:
https://github.com/phonegap-build/PushPlugin (deprecated)
https://github.com/phonegap/phonegap-plugin-push (new one)
Both are supported by ngCordova, but only the deprecated version is documented.
The deprecated version is $cordovaPush
and the newer one is $cordovaPushV5, and they have completely different methods.
For me the problem was that I downloaded the cordova-plugin-push and tried to implement it with the old documentation on ngCordova site.
The code is:
/*
* Non deprecated version of Push notification events
*/
function registerV5() {
$ionicLoading.show({
template: '<ion-spinner></ion-spinner>'
});
if (ionic.Platform.is('browser')) {
alert("You are running on broswer, please switch to your device. Otherwise you won't get notifications");
$ionicLoading.hide();
return;
}
/**
* Configuration doc:
* https://github.com/phonegap/phonegap-plugin-push/blob/master/docs/API.md#pushnotificationinitoptions
*/
var GCM_PROJECT_ID = 'xxxxxx';
$cordovaPushV5.initialize({
"android": {
"clearNotifications": false,
"senderID" : GCM_PROJECT_ID
}
});
$cordovaPushV5.register().then(function (deviceToken) {
console.log("Successfully registered", deviceToken);
$scope.data.deviceToken = deviceToken;
// Below code required to configure $cordovaPushV5 notifications emitter.
// Don't pass function it's not handler.
$cordovaPushV5.onNotification();
$cordovaPushV5.onError();
$ionicLoading.hide();
}, function (error) {
console.log("Failed to registered");
console.log("error object : ", error);
$ionicLoading.hide();
});
}
$rootScope.$on('$cordovaPushV5:notificationReceived', function(event, data) {
console.log("notification received");
console.log("data object: ", data);
var foreground = data.additionalData.foreground || false;
var threadID = data.additionalData.payload.threadID || '';
var group = data.additionalData.payload.group || false;
if (foreground) {
// Do something if the app is in foreground while receiving to push - handle in app push handling
console.log('Receive notification in foreground');
} else {
// Handle push messages while app is in background or not started
console.log('Receive notification in background');
// Open FB messanger app when user clicks notification UI when app is in background.
if (typeof data.additionalData.coldstart != "undefined" && data.additionalData.coldstart == false)
if (!group)
// Open FB Messenger of specific user chat window
window.open('fb-messenger://user/' + threadID, '_system', 'location=no');
else
// Open FB Messenger of specific group chat window
window.open('fb-messenger://groupthreadfbid/' + threadID, '_system', 'location=no');
}
});
$rootScope.$on('$cordovaPushV5:errorOccurred', function(event, error) {
console.log("notification error occured");
console.log("event object: ", event);
console.log("error object: ", error);
});
More on this github article: https://github.com/driftyco/ng-cordova/issues/1125 (code from here) and in this article: https://github.com/yafraorg/yafra/wiki/Blog-Ionic-PushV5