I have the following code:
app.js:
Ti.include('logic/ui.js');
/* some code */
mainWindow.open();
ui.js:
var mainWindow = Ti.UI.createWindow({
title : 'Main Window',
backgroundColor:'transparent',
exitOnClose : true,
backgroundImage: 'view/i/bg.png',
});
var resultWebView = Titanium.UI.createWebView({
url : 'view/result.html',
backgroundColor: 'transparent'
});
mainWindow.add(resultWebView);
Problem: On devices with Android < 2.3.5, WebView does not load when the application is first loaded. But if you apply zoom, it works fine. Any ideas on how I can resolve this?
UPDATE:
If the url to the web document is internet url, then WebView always displayed without a problem.
var resultWebView = Titanium.UI.createWebView({
url : 'http://www.google.com',
backgroundColor: 'transparent'
});
Related
i need to show a pdf file located in a URL
My code is easy...
var link_condiciones;
var idioma = Left( Titanium.Locale.getCurrentLanguage().toLowerCase(),2 );
if( idioma == "es" ) {
link_condiciones = "http://micoachingapp.net/webpanel/archivos/viewTermsES.html";
}
else{
link_condiciones = "http://micoachingapp.net/webpanel/archivos/viewTermsEN.html";
}
Ti.API.info("*** Link: " + link_condiciones );
// Creamos la ventana
var winCondiciones = Ti.UI.createWindow({
backgroundColor: clr_aux4,
extendEdges:[Ti.UI.EXTEND_EDGE_TOP],
barColor: clr_primario_fuerte,
tintColor: clr_primario_suave,
title: " ",
titleControl: Ti.UI.createImageView({ image: 'images/tituloSuperior.png' }),
rightNavButton: Ti.UI.createImageView({ image: 'images/dummy.png', width: 35, height: 35, borderRadius: 5 })
});
// Construimos el visor Web
var WebView = Ti.UI.createWebView({
top: '30dp',
width: Ti.UI.FILL,
height: Ti.UI.FILL,
url: link_condiciones
})
winCondiciones.add(WebView);
var btnAceptar = Ti.UI.createButton({
title: L("txt_acepto_terminos"),
borderRadius: radioArcoBoton,
backgroundColor: color_on,
color: 'white',
height: '7%',
bottom: 3,
width: '95%'
})
btnAceptar.addEventListener("click", function(){
RegistrarFecha( fecha, navWindow, winCondiciones, winAnt1, winAnt2 );
});
winCondiciones.add(btnAceptar);
// Mostramos la ventana
if(IsAndroid()) {
winCondiciones.open();
}
else {
navWindow.openWindow(winCondiciones);
}
But i cant see the PDF, only a lote of erros in the console.
[INFO] : TiUIWebView: (main) [2621,15443] Detected com.htc.software.Sense feature com.htc.software.Sense7.0
[INFO] : WebViewFactory: Loading com.google.android.webview version 51.0.2704.81 (code 270408100)
[INFO] : cr_LibraryLoader: Time to load native libraries: 2 ms (timestamps 7860-7862)
[INFO] : cr_LibraryLoader: Expected native library version number "51.0.2704.81", actual native library version number "51.0.2704.81"
[INFO] : cr_LibraryLoader: Expected native library version number "51.0.2704.81", actual native library version number "51.0.2704.81"
[INFO] : chromium: [INFO:library_loader_hooks.cc(143)] Chromium logging enabled: level = 0, default verbosity = 0
[INFO] : cr_BrowserStartup: Initializing chromium process, singleProcess=true
[ERROR] : ApkAssets: Error while loading asset assets/natives_blob_64.bin:
...
[INFO] : *** Lenguaje: es
[INFO] : *** Valor : 2016-08-12 18:00:00
[INFO] : *** Link: http://micoachingapp.net/webpanel/archivos/viewTermsES.html
[INFO] : TiUIWebView: (main) [48206,288996] Detected com.htc.software.Sense feature com.htc.software.Sense7.0
[WARN] : cr_AwContents: onDetachedFromWindow called when already detached. Ignoring
[INFO] : cr_Ime: ImeThread is not enabled.
[ERROR] : SensorManager: uid = 10142
[INFO] : SensorManager: registerListenerImpl: listener = android.view.OrientationEventListener$SensorEventListenerImpl#31ca6080, sensor = {Sensor name="BMA255 3-axis Accelerometer", vendor="Bosch", version=1, type=1, maxRange=39.24, resolution=0.15328126, power=0.2, minDelay=10000}, delay = 200000, handler = null
[WARN] : cr_BindingManager: Cannot call determinedVisibility() - never saw a connection for the pid: 21108
[WARN] : cr_BindingManager: Cannot call determinedVisibility() - never saw a connection for the pid: 21108
that's the ful code with the problem.
Its only a window, with a pdf and a button.
Appelerador, SDK 5.3.1 GA
Android 5
you can try this.
webview.loadUrl("http://drive.google.com/viewerng/viewer?embedded=true&url=" + pdf);
WebViews can't display pdfs natively. You can try loading the url through a web based pdf reader like google docs, but you can't just display a pdf in a webview. I'm not sure why you thought you could, a WebView displays web pages, not pdfs.
Suppose your url is this:
http://www.appcelerator.com/wp-content/uploads/GettingStartedTitanium_Windows.pdf
1 - Either open the link in external browser:
Ti.Platform.openURL('http://www.appcelerator.com/wp-content/uploads/GettingStartedTitanium_Windows.pdf');
2 - Assuming that your URL directly displays the pdf file as above url, you can get the binary data using Ti.Network.HTTPClient and then you can display it in webview like this:
var url = "http://www.appcelerator.com/wp-content/uploads/GettingStartedTitanium_Windows.pdf";
var client = Ti.Network.createHTTPClient({
// function called when the response data is available
onload : function(e) {
var pdfData = this.responseData; // it contains the pdf blob data
// Construimos el visor Web
var WebView = Ti.UI.createWebView({
top: '30dp',
width: Ti.UI.FILL,
height: Ti.UI.FILL,
data : pdfData // instead of url, use pdfData blob object
});
winCondiciones.add(WebView);
},
onerror : function(e) {
Ti.API.error(e.error);
alert('error');
}
});
client.open("GET", url);
client.send();
3 - Try this also as I was also stuck in some weird issue once and after finding no help, it worked finally by adding borderRadius attribute:
// Construimos el visor Web
var WebView = Ti.UI.createWebView({
top: '30dp',
width: Ti.UI.FILL,
height: Ti.UI.FILL,
borderRadius : 2,
url: link_condiciones
});
winCondiciones.add(WebView);
If it doesn't work out for you, then you probably try to look out some module to display remote pdf file. Good Luck!!!
As I tried to run the code, the issue you are facing can be solved by putting complete url of what you provided in one of your comment.
Put this :
http://micoachingapp.net/webpanel/archivos/viewTermsES.html
instead of micoachingapp.net/webpanel/archivos/viewTermsES.html
Now, what I saw weird is that if I open up this url http://www.micoachingapp.net/webpanel/archivos/viewTermsES.html, I wonder why it takes me to some other pdf by simply adding www in it.
Carefully look at the all URLs I mentioned above, here are these:
Yours - micoachingapp.net/webpanel/archivos/viewTermsES.html
If you paste your URL in any browser and then you will copy it again from the address bar, you will get this: http://micoachingapp.net/webpanel/archivos/viewTermsES.html
Now add www - http://www.micoachingapp.net/webpanel/archivos/viewTermsES.html
In WebView
URL 1 shows the error you mentioned in your question.
URL 2 is the actual url as displayed by chrome or safari or any desktop browser.
URL 3 takes to some other pdf...How is that possible???
So your solution lies within these 3 URLs, maybe it is a domain issue or don't know what it is as I never faced such issue.
But for sure, it will work if you open it in external device browser using Ti.Platform.openURL
I try to show YT video in my application (Appcelerator, Android). I found that the best way is to show embeded video in WebView, so I do it with such code:
var webView = Ti.UI.createWebView({
url: 'https://www.youtube.com/embed/LTRfmqc0KBg',
enableZoomControls: false,
scalesPageToFit: true,
scrollsToTop: false,
showScrollbars: false
});
but video does not load (I see only black screen - instead of webview's white). WebView works properly because it shows other pages.
Then you can try this
var Win = Titanium.UI.createWindow({
title : 'Video View Demo',
backgroundColor : '#fff'
});
var video_url = 'https://www.youtube.com/watch?v=bSiDLCf5u3s';
var movie = '<html><head></head><body style="margin:0"><embed id="yt" src="' + video_url + '" type="application/x-shockwave-flash" width="480" height="266"></embed></body></html>';
var webView = Ti.UI.createWebView({
top:0,
left:0,
width:480,
height:266,
url:video_url,
html:movie
});
Win.add(webView);
Win.open();
You can call the device default youtube app to open the url for the user. See the below code
var Win = Titanium.UI.createWindow({
title : 'Youtube Video View Demo',
backgroundColor : '#fff'
});
var button = Titanium.UI.createButton({
title: 'Hello',
top: 10,
width: 100,
height: 50
});
button.addEventListener('click',function(e)
{
Titanium.Platform.openURL('https://www.youtube.com/watch?v=bSiDLCf5u3s');
});
Win.add(button);
Win.open();
Thanks.
I found that embedded videos wouldn't work on Android, while doing fine on iOS.
However switching form using the webviews url property to load the video, to using the setHtml() function works. The way to do this is by using the Youtube iframe api.
var videoUrl = 'https://www.youtube.com/embed/' + videoId + '? autoplay=1&autohide=1&cc_load_policy=0&color=white&controls=0&fs=0&iv_load_policy=3&modestbranding=1&rel=0&showinfo=0';
var playerWidth = $.youtubeWebView.width;
var playerHeight = $.youtubeWebView.height;
var html = '<iframe id="player" type="text/html" width="'+playerWidth+'" height="'+playerHeight+'" src="'+videoUrl+'" frameborder="0"></iframe>';
$.youtubeWebView.setHtml(html);
Heads up, iframes can be a pain, add this in the load event to get rid of the wierd white padding on the top & left side
this.evalJS('document.getElementsByTagName("body")[0].style.margin=0;');
Something like this:
$.youtubeWebView.addEventListener('load', function(){
this.evalJS('document.getElementsByTagName("body")[0].style.margin=0;');
var showYoutubeTimer = setTimeout(function() {
$.activityIndicator.hide();
$.youtubeWebView.opacity = 1;
clearTimeout(showYoutubeTimer);
}, 300);
});
Please excuse the ugly code this is here just as the simplest possible version of my actual code that I can use to reproduce my error. I am basically using a WebView in titanium to open a locally held .htm file so that I can leverage HTML5 graphics capabillities. What I am doing works fine. The problem is that I need to pass some data to the htm file which I am doing exactly as the docs recommend - using Ti.App.fireEvent - and this works ... once. But if I navigate away from the window and then navigate back again it fails and gives me a NS_ERROR_NOT_AVAILABLE. I have tried this code in firefox as a web preview and on Android device and emulator with the same issue in each. Clearly there is some issue with it not loading the same way if the view is called back, I am guessing it is pulled back off the stack which is messing with the 'load' event listener or something, but I have no idea how to fix it. Here is a simplified version of my code, just to demonstrate the issue:
app.js
Titanium.UI.setBackgroundColor('#000');
var win = Ti.UI.createWindow({
layout: 'vertical',
});
var wv = Ti.UI.createWebView({
url: 'test.htm',
height: '50%'
});
var but = Ti.UI.createButton({
width: 100,
height: 50,
title: 'Press',
});
var wvopen = false;
but.addEventListener('click', function() {
if (wvopen === false) {
win.add(wv);
wvopen = true;
} else {
win.remove(wv);
wvopen = false;
}
});
wv.addEventListener('load', function() {
Ti.App.fireEvent('go');
});
win.add(but);
win.open();
And the .htm file:
test.htm
<!doctype html>
<html>
<head>
<title>Test</title>
</head>
<body>
<p>A Little Test</p>
<script>
var Ti = window.parent.Ti;
Ti.App.addEventListener('go', function(){
alert(1);
});
</script>
</body>
</html>
Try this,
but.addEventListener('click', function() {
if (wvopen === false) {
win.add(wv);
wvopen = true;
} else {
win.remove(wv);
wv.release();
wvopen = false;
}
});
I found the answer myself eventually. It is in the docs but realising what the problem actually is and why it is happening is not always simple so I feel it is worth me answering here myself for others use.
The key point is this:
"Keep in mind that app-level events are global, which means they remain in context the entire time your app is running (unless you remove them). This also means that any objects they reference will also remain in scope while your app runs. This could prevent those objects from being garbage collected. See the Managing Memory and Finding Leaks chapter for more information."
~ Titanium docs.
link: https://wiki.appcelerator.org/display/guides2/Event+Handling#EventHandling-Application-LevelEvents
So basically the event listener will exist even if it is not loaded and you try to delete the context in which it exists. So you must delete both the event listener and nullify the view that holds it.
In practice the implementation may vary a little depending on your specifics, but this is what I came up with.
NB ... there may be more efficient methods to do this in which case please let me know.
app.js
/*
* Build window and buttons
*/
var win = Ti.UI.createWindow({
layout: 'vertical',
backgroundColor:'black'
});
var but = Ti.UI.createButton({
top: 20,
width: 200,
height: 50,
title: 'Toggle WV',
});
var but2 = Ti.UI.createButton({
top: 20,
width: 200,
height: 50,
title: 'Fire Event'
});
var wv;
function newWv(){
wv = Ti.UI.createWebView({
top:20,
right: 20,
left: 20,
height: '50%',
url: 'test.htm',
});
}
win.add(but);
win.add(but2);
/*
* Main functionality goes here of tests goes here.
*/
var isVisible = false;
but.addEventListener('click', function() {
if (isVisible) {
win.remove(wv);
Ti.App.fireEvent('close');
wv = null;
isVisible = false;
} else {
newWv();
win.add(wv);
isVisible = true;
}
});
but2.addEventListener('click', function() {
try{
Ti.App.fireEvent('go');
} catch(e) {
alert(e);
}
});
win.open({modal:true});
And then a few changes in the htm file:
test.htm
<!doctype html>
<html>
<head>
<title>Test</title>
</head>
<body>
<p>A Little Test</p>
<script>
var Ti = window.parent.Ti;
var go = function() {
alert('called by Titanium app');
};
var close = function() {
Ti.App.removeEventListener('go',go);
Ti.App.removeEventListener('close',close);
};
window.addEventListener('load', function() {
Ti.App.addEventListener('go', go);
Ti.App.addEventListener('close', close);
});
</script>
</body>
</html>
this code returns:
Cannot read property 'getPicture' of undefined
Have no idea what im doing wrong, can you please help me with the code?
My App:
angular.module('Todo', ['ionic', 'Todo.controllers','ngStorage',
'Todo.services', 'ngCordova'])
my Controller:
.controller('profileEditCtrl', function($scope,Camera, $localStorage,
$cordovaCamera)
{
$scope.$storage = $localStorage.$default({ data:[]});
$scope.takePicture = function()
{
navigator.camera.getPicture(onSuccess, onFail, { quality: 50,
destinationType: Camera.DestinationType.DATA_URL });
function onSuccess(imageData) {
var image = document.getElementById('myImage');
image.src ="data:image/jpeg;base64," + imageData;
}
function onFail(message) {
alert('Failed because: ' + message);
}
}});
Your code is correct, just add an html button with ng-click="takePicture()".
There is no problem here, It's sure that the browser "cannot read
property 'getPicture' of undefined" because it has no configuration
for a mobile camera that you defined, which means you should test your application on
a real device using:
> ionic run android.
Notice that the new update of Google Chrome has a new feature which
helps your test your device on the browser if it is connected to the
PC/laptop, for testing go to chrome's navigation panel >> More tools >> Inspect devices
or just go to this link:
chrome://inspect/#devices
I'm sure your camera will function normally if you have the plugin cordova plugin add org.apache.cordova.camera installed in the app,
I hope this helps you.
After trying various solutions with no luck for my cordova project, I simply went ahead to use the built-in JavaScript APIs. Essentially:
async function startCapturing() { // get ready to shoot
await getPermission('android.permission.CAMERA');
let stream = await navigator.mediaDevices.getUserMedia({ video: {width: 480, height: 320, facingMode:'environment' }, audio: false });
let video = document.getElementById("pVideo"); // a <video> element
video.srcObject = stream;
video.play();
video.style.display = "block";
}
function shootPhoto(){ // take a snapshot
let video = document.getElementById("pVideo");
let canvas = document.getElementById("pCanvas"); // a <canvas> element
let context = canvas.getContext('2d');
context.drawImage(video,0,0,480,320);
document.getElementById('fsPhotoI').src = Photo.current.src = canvas.toDataURL('image/png');
Photo.current.changed = Profile.current.changed = true;
video.style.display = "none";
}
In particular, some plugins did not work for me because they could't use the Android rear camera right away. The following in getUserMedia(...) does the trick:
facingMode:'environment'
Also make sure you have the CAMERA permission in your AndroidManifest.xml.
Greetings,
I'm trying to simply display a blank textfield (I know), but it's not working?
I must be making some simple error.
Here is my app.js:
Titanium.UI.setBackgroundColor('#FFF');
var win1=Titanium.UI.createWindow({
title:'Login',
backgroundColor:'#FFF'
});
var uname = Titanium.UI.createTextField({
color:'#336699',
height:35,
top:50,
width:250,
borderStyle:Titanium.UI.INPUT_BORDERSTYLE_ROUNDED
});
win1.add(uname);
Am I missing something? The above should work, right?
I'm using Android emulator on Ubuntu x86_64
When I use tabs the uname and label appear ok:
Titanium.UI.setBackgroundColor('#000');
var tabGroup = Titanium.UI.createTabGroup();
var win1 = Titanium.UI.createWindow({
title:'Tab 1',
backgroundColor:'#fff'
});
var tab1 = Titanium.UI.createTab({
icon:'KS_nav_views.png',
title:'Tab 1',
window:win1
});
var uname=Titanium.UI.createTextField({
color:'#336699',
height:35,
top:50,
width:250,
borderStyle:Titanium.UI.INPUT_BORDERSTYLE_ROUNDED
});
var label1=Titanium.UI.createLabel({
color:'#999',
text:'hello',
font:{fontSize:20,fontFamily:'Helvetica Neue'},
textAlign:'center',
width:'auto'
});
win1.add(uname);
win1.add(label1);
tabGroup.addTab(tab1);
tabGroup.open();
But how do I get rid of the tabs???
I've tried several versions of Android (1.6 API and 2.2 API)
Many thanks in advance,
Update: the solution is:
Add the following line:
win1.open({fullscreen:true});
is this on the end of you app.js
win1.open({fullscreen:true});