These days i am trying to run an existing code from Adobe's Technical Evangelist Andrew Trice. The concept is to connect a database.com DB to phone gap application. here is the tutorial with the source code :
http://wiki.developerforce.com/page/Building_PhoneGap_Mobile_Applications_Powered_by_Database.com
THE ISSUE :
AFTER SUCCESSFUL INSTALLATION OF THE Childbrowser there is a specific error in the code :
Uncaught type error: cannot read property "ChildBrowser" of undefined at file:///android_asset/www/js/salesforceWrapper.js:17
here is the full code : ( i put comment in the line with the error)
function SalesforceWrapper() {
/* AUTHENTICATION PARAMETERS */
this.loginUrl = 'https://login.salesforce.com/';
this.clientId = '3MVG99qusVZJwhsmjZIlEaUsFRnadOib8Kv_MPwooFMEi.XpChrZ5cVEcKU_7NR1zfQjjmdHI7wMARXnLlgku';
this.redirectUri = 'https://login.salesforce.com/services/oauth2/success';
/* CLASS VARIABLES */
this.cb = undefined; //ChildBrowser in PhoneGap
this.client = undefined; //forceTk client instance
this.init();
}
SalesforceWrapper.prototype.init = function() {
this.client = new forcetk.Client(this.clientId, this.loginUrl);
// line 17 with the error
this.cb = window.plugins.childBrowser;
}
SalesforceWrapper.prototype.login = function (successCallback) {
this.loginSuccess = successCallback;
var self = this;
self.cb.onLocationChange = function (loc) {
if (loc.search(self.redirectUri) >= 0) {
self.cb.close();
self.sessionCallback(unescape(loc));
}
};
self.cb.showWebPage(self.getAuthorizeUrl(self.loginUrl, self.clientId, self.redirectUri));
}
SalesforceWrapper.prototype.getAuthorizeUrl = function (loginUrl, clientId, redirectUri) {
return loginUrl + 'services/oauth2/authorize?display=touch' + '&response_type=token&client_id=' + escape(clientId) + '&redirect_uri=' + escape(redirectUri);
}
SalesforceWrapper.prototype.sessionCallback = function(loc) { var oauthResponse = {};
var fragment = loc.split("#")[1];
if (fragment) {
var nvps = fragment.split('&');
for (var nvp in nvps) {
var parts = nvps[nvp].split('=');
oauthResponse[parts[0]] = unescape(parts[1]);
}
}
if (typeof oauthResponse === 'undefined' || typeof oauthResponse['access_token'] === 'undefined') {
console.log("error");
} else {
this.client.setSessionToken(oauthResponse.access_token, null, oauthResponse.instance_url);
if ( this.loginSuccess ) {
this.loginSuccess();
}
}
this.loginSuccess = undefined;
}
ADOBE'S PHONE GAP IS A DANGEROUS TOOL , BUT IT IS STILL SO TOUGH TO MANIPULATE.
THANK YOU APRIORI FOR YOUR POSSIBLE PROPOSALS . AT THIS POINT I DON'T EXPECT TO GET THE ANSWER. I KNOW THAT THERE IS A BIG DISTANCE...
well people the problem was caused because of the index.html in which the reference of the childbrowser.js was in different folder.
it was in :
<script type="text/javascript" src="js/libs/ChildBrowser.js"></script>
instead of :
<script type="text/javascript" src="js/ChildBrowser.js"></script>
SO PEOPLE BE CAREFULL!!!
NOW MY PROBLEM HAS TO DO WITH ANOTHER FUNCTION BUT I THINK THAT IT IS SOMETHING SIMILAR.
THANK YOU ALL!
PLEASE TRY TO ANSWER IF YOU KNOW SOMETHING.
Related
I am building a mobile app for body measurement through photo I capture. how I can use OpenCV for the same? How to integrate OpenCV with Ionic framework? Kindly help.
Essentially you can pull in a flavor of the opencv.js framework. The way I've done it is by pulling down some reference like https://docs.opencv.org/3.4.1/opencv.js, and then hosting it somewhere (in case opencv moves it on you). Then include that script in the Ionic project. Be careful how you do that though. It is a big file, so it could take the app longer to load. Some options I've used:
Local Asset
Store the js file in the local assets, and include it in the index.js. If the Ionic app is deployed as a native app, then this asset is already in the app and fairly fast to load.
<script src="assets/js/opencv.js" async></script>
Dynamically load the file (example below)
async ionViewDidLoad() {
let loadingScreen = this.loadingCtrl.create({ content: "Loading Scripts. Please Wait..." });
//Show loading screen & load scripts
try {
await loadingScreen.present();
await this.loadScript();
}
catch (error) {
this.errorMessage = "We had some trouble loading scripts...";
}
finally {
loadingScreen && loadingScreen.dismiss();
}
}
public loadScript(): Promise<any> {
return new Promise((resolve, reject) => {
var isFound = false;
var scripts = document.getElementsByTagName("script")
for (var i = 0; i < scripts.length; ++i) {
if (scripts[i].getAttribute('src') != null &&
scripts[i].getAttribute('src').includes("opencv")) {
isFound = true;
return resolve();
}
}
if (!isFound) {
var dynamicScripts = ["https://docs.opencv.org/3.4.1/opencv.js"];
for (var i = 0; i < dynamicScripts.length; i++) {
let scriptNode = document.createElement('script');
scriptNode.src = dynamicScripts[i];
scriptNode.type = 'text/javascript';
scriptNode.async = false;
scriptNode.charset = 'utf-8';
document.getElementsByTagName('head')[0].appendChild(scriptNode);
scriptNode.onload = resolve;
}
}
});
}
I'm making an app capable of take photos and upload them to a server. The phone will save the id generated.
I made a class abstractApp that creates an App object with a couple of helpers and variables. I'm using Framework7.
var App;
document.addEventListener("deviceready", function() {
App = new abstractApp();
var i;
App.f7Ref = new Framework7({init: false});
for (i = 0; i < App.constants.views.length; i++)
{
if (i==0)
App.mainView = App.f7Ref.addView (
App.constants.views[i].selector,
App.constants.views[i].settings );
else
App.f7Ref.addView (
App.constants.views[i].selector,
App.constants.views[i].settings );
}
// Checks if there exists register of remote photos
if ( App.local.get('remotephotos', false) == null || App.local.get('remotephotos', false) == '' )
{
App.remotephotos = [];
App.local.set('remotephotos', []);
}
else
{
App.remotephotos = App.local.get('remotephotos');
}
// Checks if there exists register of local photos
if ( App.local.get('localphotos', false) == null || App.local.get('localphotos', false) == '' )
{
App.localphotos = [];
App.local.set('localphotos', []);
}
else
{
App.localphotos = App.local.get('localphotos');
}
for (i = 0; i < appControllers.length; i++)
{
appControllers[i].apply(App);
}
console.log(App);
}, false);
In appControllers I'm saving functions related to each page (so it is a bit more organized). With only index and new-photo controllers I have no problem, I can attach events to elements and navigate between views. The problem is calling the camera object.
window.appControllers.push(function()
{
var $$ = Dom7;
var Ref = this.f7Ref;
var server = new serverInterface();
var photos = this.remotephotos;
var App = this;
Ref.onPageInit('new', function (page) {
Ref.alert('entra', 'entra');
$$('.capture').on('click', function () {
Ref.alert('Click', 'Click detected');
navigator.camera.getPicture(onSuccess, onFail,
{
quality: 20,
destinationType: destinationType.FILE_URI
});
function onSuccess(imageURI) {
Ref.alert('Photo captured.', 'Bien');
}
function onFail(message) {
Ref.alert('There was a problem.', 'Ups');
}
});
});
});
So, I enter the new page and I click the button with cass capture and the alert (click detected) appears, but it doesn't show the camera to take the photo.
I'm using Phonegap Build and an android phone, do you have any idea of what's happening?
Thank you very much in advance
The problem wasn't the javascript code I quoted.
I was loading the camera plugin in the config.xml like this
<gap:plugin name="org.apache.cordova.camera" />
But it should be loaded this way:
<plugin name="cordova-plugin-camera" />
If the plugin is not loaded correctly, in Phonegap Build appears: version n/a installed. In this case, when it is correctly loaded, appears: version 2.1.0 installed.
More information about this thread can be found here: http://phonegap.com/blog/2015/11/19/config_xml_changes_part_two/
Hope it helps someone else too
Regards
I'm trying to play multi-language audio tracks on chromecast. It plays the video/audio files but it does not switch from English to Spanish. I can switch using the same file in a silverlight player. I've set my chromecast player language and my android phone language to be spanish. In the Google Cast SDK Developer console, I added spanish as an alternate track.
I've added my custom player using the code specified in the google guides, however the code in the guides does not appear to work from a straight copy and paste. Can someone direct me as to why protocol.getStreamCount() is 0? Is the timing of the call correct? Here's the entire player that I'm using, pay particular attention to window.changeLanguage = function()... and the changeLanguage call. Any help is extremely appreciated!
<html>
<head>
<title>Test Player</title>
<script type="text/javascript" src="//www.gstatic.com/cast/sdk/libs/receiver/2.0.0/cast_receiver.js"></script>
<script type="text/javascript" src="//www.gstatic.com/cast/sdk/libs/mediaplayer/1.0.0/media_player.js"></script>
<link rel="stylesheet" type="text/css" href="chromecast.css" />
</head>
<body>
<video id='vid' />
<script type="text/javascript">
if (window.location.href.indexOf('Debug=true') != -1) {
cast.receiver.logger.setLevelValue(cast.receiver.LoggerLevel.DEBUG);
cast.player.api.setLoggerLevel(cast.player.api.LoggerLevel.DEBUG);
}
var mediaElement = document.getElementById('vid');
var protocol = null;
// Create the media manager. This will handle all media messages by default.
window.mediaManager = new cast.receiver.MediaManager(mediaElement);
window.defaultOnLoad = mediaManager.onLoad;
mediaManager.onLoad = function (event) {
if (window.player !== null) {
player.unload(); // Must unload before starting again.
window.player = null;
}
if (event.data['media'] && event.data['media']['contentId']) {
console.log('Starting media application');
var url = event.data['media']['contentId'];
window.host = new cast.player.api.Host({'mediaElement':mediaElement, 'url':url});
var ext = url.substring(url.lastIndexOf('.'), url.length);
var initStart = event.data['media']['currentTime'] || 0;
var autoplay = event.data['autoplay'] || true;
mediaElement.autoplay = autoplay; // Make sure autoplay get's set
if (url.lastIndexOf('.m3u8') >= 0)
{
// HTTP Live Streaming
protocol = cast.player.api.CreateHlsStreamingProtocol(host);
}
else if (url.lastIndexOf('.mpd') >= 0)
{
// MPEG-DASH
protocol = cast.player.api.CreateDashStreamingProtocol(host);
}
else if (url.indexOf('.ism/') >= 0)
{
// Smooth Streaming
protocol = cast.player.api.CreateSmoothStreamingProtocol(host);
}
// How to override a method in Host. I know that it's safe to just provide this
// method.
host.onError = function(errorCode) {
console.log("Fatal Error - " + errorCode);
if (window.player) {
window.player.unload();
window.player = null;
}
};
console.log("we have protocol " + ext);
if (protocol !== null) {
console.log("Starting Media Player Library");
window.player = new cast.player.api.Player(host);
window.player.load(protocol, initStart);
changeLanguage();
}
else {
window.defaultOnLoad(event); // do the default process
}
}
}
window.changeLanguage = function() {
var currentLanguage = null;
var streamCount = protocol.getStreamCount();
console.log("streamCount: " + streamCount);
var streamInfo;
for (var i = 0; i < streamCount; i++) {
console.log("isStreamEnabled " + i + "? " + protocol.isStreamEnabled(i));
if (protocol.isStreamEnabled(i)) {
streamInfo = protocol.getStreamInfo(i);
console.log("streamInfo isAudio? " + streamInfo.mimeType.indexOf('audio'));
if (streamInfo.mimeType.indexOf('audio') === 0) {
if (streamInfo.language) {
console.log("streamInfo.language: " + streamInfo.language);
currentLanguage = i;
break;
}
}
}
}
if (currentLanguage === null) {
currentLanguage = 0;
}
i = currentLanguage + 1;
console.log("i: " + i);
console.log("currentLanguage: " + currentLanguage);
while (i !== currentLanguage) {
if (i === streamCount) {
console.log("resetting i to 0");
i = 0;
}
streamInfo = protocol.getStreamInfo(i);
if (streamInfo.mimeType.indexOf('audio') === 0) {
protocol.enableStream(i, true);
protocol.enableStream(currentLanguage, false);
console.log("Enabling: " + i);
console.log("Disabling: " + currentLanguage);
break;
}
i++;
}
if (i !== currentLanguage) {
console.log("reloading window player" + window.player);
window.player.reload();
}
};
window.player = null;
console.log('Application is ready, starting system');
window.castReceiverManager = cast.receiver.CastReceiverManager.getInstance();
castReceiverManager.start();
</script>
</body>
</html>
Chromecast Console:
Application is ready, starting system
Starting media application
we have protocol .ism/manifest
Starting Media Player Library
streamCount: 0
i: 1
currentLanguage: 0
EDIT
I went into console and post loading called the following command:
this.protocol.getStreamCount()
2
So this is clearly a timing issue. I need to call changeLanguage once the stream has fully loaded. I'm investigating when the appropriate time to call it is. I'd appreciate any help but I'll try to google this answer now that I'm positive it's a timing issue.
Answer is:
host.onManifestReady = function() {
changeLanguage();
};
This will provide the correct timing for when to pull the alternate audio tracks.
I am trying to generate a PDF using the jsPDF library (https://github.com/MrRio/jsPDF) from within a mobile Cordova app. I am currently testing the app on an Android 4.0.4 device but it also needs to run on Windows mobile 8. The text in the PDF document is shown correctly however any images are scrambled. See image below
I did find this page (https://coderwall.com/p/nc8hia) that seemed to indicate there is a problem with jsPDF displaying images in Cordova (see comments) but the author never posted the follow-up. Has anyone been able to use jsPDF with Cordova and properly add images to the generated PDF? My code is below, any assistance or advice would be greatly appreciated.
function demoReceipt() {
var img = new Image();
img.onError = function() {
alert('Cannot load image: "' + url + '"');
};
img.onload = function() {
createPdf2(img);
};
img.src = 'img/testlogo.png';
}
function createPdf2(myLogo) {
// var doc = new jsPDF('p', 'pt', 'jontype');
var doc = new jsPDF('p', 'pt', 'letter');
doc.setProperties({
title : 'Fueling Receipt',
author : 'Jon Hoffman',
creater : 'Jon Hoffman'
});
doc.addImage(myLogo, 'PNG', 5, 5, 140, 30);
doc.setFontSize(12);
doc.text(10, 40, 'Sample PDF receipt');
doc.setFontSize(8);
doc.text(10, 45, 'Smaller text - new');
var pdfOutput = doc.output();
//NEXT SAVE IT TO THE DEVICE'S LOCAL FILE SYSTEM
//Requires cordova plugin add org.apache.cordova.file
console.log("file system...");
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function(fileSystem) {
console.log(fileSystem.name);
console.log(fileSystem.root.name);
console.log(fileSystem.root.fullPath);
fileSystem.root.getDirectory("myPDFs", {
create : true,
exclusive : false
}, function(dir) {
fileSystem.root.getFile("myPDFs/test.pdf", {
create : true
}, function(entry) {
var fileEntry = entry;
console.log(entry);
entry.createWriter(function(writer) {
writer.onwrite = function(evt) {
console.log("write success");
};
console.log("writing to file");
writer.write(pdfOutput);
}, function(error) {
console.log(error);
});
}, function(error) {
console.log(error);
});
}, function(error) {
});
}, function(event) {
console.log(evt.target.error.code);
});
}
I solved the issue with help from this blog post: https://coderwall.com/p/nc8hia. There does seems to be significant differences between the 0.90 version used in that post and the version that I am using from https://github.com/MrRio/jsPDF however the solution is pretty much the same.
First off, in the version from MyRio, you can get the PDF generation working without fixing the Blob issue noted in Igor’s post. All you need is to generate the PDF output by calling “doc.ouput()” and then save it using the Cordova filesystem plugin. So I thought I did not have to create the Blob (this is where I was wrong).
Igor (from the coderwall post) responded back to my question with some additional code but when I searched the jspdf.js file from MyRio version, I saw that the code (more compact version) was already in the code on lines 734 – 738:
var data = buildDocument(), len = data.length,
ab = new ArrayBuffer(len), u8 = new Uint8Array(ab);
while(len--) u8[len] = data.charCodeAt(len);
return new Blob([ab], { type : "application/pdf" });
But I also notice that the blob creation code that Igor fixed in his initial post was at the end of this block of code. So I commented out the “return new Blob([ab], { type : “application/pdf”});” line and put in the following code from Igor’s post with minor variable name changes:
try
{
var blob = new Blob([ab], {type: "application/pdf"});
console.debug("case 1");
return blob;
}
catch (e)
{
window.BlobBuilder = window.BlobBuilder ||
window.WebKitBlobBuilder ||
window.MozBlobBuilder ||
window.MSBlobBuilder;
if (e.name == 'TypeError' && window.BlobBuilder)
{
var bb = new BlobBuilder();
bb.append(ab);
console.debug("case 2");
return bb.getBlob("application/pdf");
}
else if (e.name == "InvalidStateError")
{
// InvalidStateError (tested on FF13 WinXP)
console.debug("case 3");
return new Blob([ab], {type: "application/pdf"});
}
else
{
// We're screwed, blob constructor unsupported entirely
console.debug("Errore");
}
}
Then when I generate that pdfOutput, in my code, I changed
var pdfOutput = doc.output();
to
var pdfOutput = doc.output(“blob”);
and it worked.
I hope this post is able to help out others experiencing the same issues.
var style1 = document.createElement("link");
style1.id = "rel";
style1.rel = "stylesheet";
style1.href = "http://www.mysite.com/css.css";
style1.onload = function(){document.body.innerHTML+="fffffff";};
document.getElementsByTagName("head")[0].appendChild(style1);
This code works in Chrome/Firefox, and yet stock browsers on my Froyo (2.3) and Jellybean (4.1) Android devices will print nothing. What's the problem? I'd like if I could execute some js onload of a link. Anything else would in my case amount to a hack. :/
The problem isn't innerHTML. Try it with alerts if you want (at your own peril).
Another answer mentions checking for this functionality by doing
var huh = 'onload' in document.createElement('link');
..but this is true in both stock browsers! wtf guys?
Android browser doesn't support "onload" / "onreadystatechange" events for element: http://pieisgood.org/test/script-link-events/
But it returns:
"onload" in link === true
So, my solution is to detect Android browser from userAgent and then wait for some special css rule in your stylesheet (e.g., reset for "body" margins).
If it's not Android browser and it supports "onload" event- we will use it:
var userAgent = navigator.userAgent,
iChromeBrowser = /CriOS|Chrome/.test(userAgent),
isAndroidBrowser = /Mozilla\/5.0/.test(userAgent) && /Android/.test(userAgent) && /AppleWebKit/.test(userAgent) && !iChromeBrowser;
addCssLink('PATH/NAME.css', function(){
console.log('css is loaded');
});
function addCssLink(href, onload) {
var css = document.createElement("link");
css.setAttribute("rel", "stylesheet");
css.setAttribute("type", "text/css");
css.setAttribute("href", href);
document.head.appendChild(css);
if (onload) {
if (isAndroidBrowser || !("onload" in css)) {
waitForCss({
success: onload
});
} else {
css.onload = onload;
}
}
}
// We will check for css reset for "body" element- if success-> than css is loaded
function waitForCss(params) {
var maxWaitTime = 1000,
stepTime = 50,
alreadyWaitedTime = 0;
function nextStep() {
var startTime = +new Date(),
endTime;
setTimeout(function () {
endTime = +new Date();
alreadyWaitedTime += (endTime - startTime);
if (alreadyWaitedTime >= maxWaitTime) {
params.fail && params.fail();
} else {
// check for style- if no- revoke timer
if (window.getComputedStyle(document.body).marginTop === '0px') {
params.success();
} else {
nextStep();
}
}
}, stepTime);
}
nextStep();
}
Demo: http://codepen.io/malyw/pen/AuCtH