Android + Python + webView some problems - android

Question 1:
I'm trying to make an android application with python and WebView.
I wonder if I can get a python variable and send it to html and save them in a variable in javascript.
I tried this but does not work:
script.py
import android
import os, sys
ruta_del_proyecto = os.path.dirname(os.path.realpath(__file__))
droid = android.Android()
droid.webViewShow(ruta_del_proyecto + '/ui/prueba.html?ruta_del_proyecto=5')
print ruta_del_proyecto + '/ui/prueba.html?ruta_del_proyecto=5'
prueba.html
<html>
<!--urta cel: file:///sdcard/sl4a/scripts/test1/ -->
<head>
<title>prueba</title>
<script>
var droid = new Android();
function getUrlVars() {
var vars = {};
var parts = window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(m,key,value) {
vars[key] = value;
});
return vars;
}
var ruta_del_proyecto = getUrlVars()["ruta_del_proyecto"];
alert (ruta_del_proyecto);
</script>
</head>
<body>
</body>
</html>
Question 2:
When I make the script.py in to APK with "The Android Java IDE (AIDE)" , then install and open, WebView don't open
The python code are execute but WebView don't open
Any idea?

There is a simple hack you can do. Webkit WebView has the "load-finished" event that triigers after your page loads and after which you can execute your JavaScript function:
def on_load_finished(webview, frame):
browser.execute_script('your-js-function('+yourVariable+');')
browser = webkit.WebView()
browser.connect("load-finished", on_load_finished)
Remember, you can pass dictionaries as an argument by serializing them with json module and deserializing them in JS!

Related

Websockets in WebViews failing to connect, returning code 1006

I have created a simple websocket in an HTML page that works great and connects fine in all of the web browsers. However, when I load it in a web view like in an Android App it fails to connect and returns the code 1006. It is trying to connect to a different URL/endpoint so I am thinking this might be a CORS issue. I am building for a minimum target of API 23.
<!DOCTYPE html>
<html>
<body>
<h1>Socket Connect</h1>
<div id="container"></div>
</body>
<script>
const div = document.getElementById('container');
try {
console.log('connect');
var ws = new WebSocket('wss://anotherserver.com:3000');
ws.binaryType = 'arraybuffer';
}
catch (err) {
}
ws.onerror = function (error) {
// error is always blank
console.log('error');
};
ws.onopen = function () {
div.textContent = 'Opened';
console.log('opened');
};
ws.onclose = function (error) {
// always = 1006
div.textContent = error.code;
console.log(error.code);
};
</script>
</html>
I have read a few other posts about setting some options in my code and I have done that. See here
myWebView.getSettings().setAppCacheEnabled(true);
myWebView.getSettings().setDatabaseEnabled(true);
myWebView.getSettings().setDomStorageEnabled(true);
myWebView.getSettings().setCacheMode(currentCacheMode); /* use cache if not expired */
myWebView.getSettings().setJavaScriptEnabled(true);
I have set cleartext in my manifest as well
It ended up being a CORS issue.

Passing data to local html file in android webView

I have some difficulties when trying to pass data to my html file. My html file is located at project root inside assets folder. In short, i am displaying my html file inside a webView.
This is portion of my mainActivity.kt, which is used to populate my webView
mWebView = findViewById(R.id.activity_main_webview);
val webSettings = mWebView.settings
webSettings.javaScriptEnabled = true
mWebView.loadUrl("file:///android_asset/googlechart.html");
and here is portion of my googlechart.html, which is stored locally inside assets folder
var dataRow = [["mushroom", 1], ["fish", 3]]
var data = new google.visualization.DataTable();
data.addColumn('string', 'Topping');
data.addColumn('number', 'Slices');
data.addRows(dataRow);
I want to pass data from mainActivity.kt to my googlechart.html, per answer at Passing data from java class to Web View html, it didn't explain how to pass data to a html file which is stored inside project root. How can i achieve that ?
Any help or insight is appreciated.
Simple solution
use Query when loadUrl()
get document.location.href in script
deal with your data
decode string, split, etc
example
If data is json
android
val json = JsonObject().apply {
addProperty("age","28")
addProperty("name","john")
addProperty("contents","test")
}
val url = "file:///android_asset/test.html?$json"
binding.webView.loadUrl(url)
local .html
<!DOCTYPE html>
<html>
<body>
<H1>test</H1>
<oi id="list">
</oi>
<script type="text/javascript">
function makeList() {
const getOiTag = document.getElementById("list");
const decodeUrl = decodeURI(document.location.href);
const jsonStr = decodeUrl.split("?")[1];
const json = JSON.parse(jsonStr);
for(i in json){
const li = document.createElement("li")
li.textContent = i + " : " + json[i];
getOiTag.appendChild(li);
}
}
makeList()
</script>
</body>
</html>

MathJax not rendering correctly

I am currently using this library in my app: https://github.com/kexanie/MathView
which is used to convert text into maths, it uses TeX/MathJax.
This was working as expected:
MathView mv = new MathView(context, null);
mv.setEngine(MathView.Engine.MATHJAX);
mv.config("MathJax.Hub.Config({\n" +
"jax: [\"input/TeX\",\"output/HTML-CSS\"],\n" +
"displayAlign: \"left\"" +
"});"
);
mv.setText(context.getString(id));
where "id" pointed to a resource in strings.xml file.
Now, I changed it to be contained inside a file, and getting it from there.
MathView mv = new MathView(context, null);
mv.setEngine(MathView.Engine.MATHJAX);
mv.config("MathJax.Hub.Config({\n" +
"jax: [\"input/TeX\",\"output/HTML-CSS\"],\n" +
"displayAlign: \"left\"" +
"});"
);
String a= text;
mv.setText(a);
where text is received from the file, but is same as the earlier one in strings.xml, I logged that to verify.
But now the output is broken. It doesn't recognise the text correctly
"\frac{a}{b}" earlier used to be "a/b", now it is "fracab"
Is it a library issue?
I have used MathJax in angular4 project. It might help you out in your project as well.
use cdnjs link for mathjax library:
<script type="text/javascript" async
src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?
config=TeX-MML-AM_CHTML"></script>
create mathjax directive:
import {Directive, ElementRef, Input, OnChanges} from'#angular/core';
declare var MathJax:any;
#Directive({
selector : '[mathText]',
})
export class MathTextDirective implements OnChanges {
constructor(public elementRef: ElementRef) {
this.hostEl = elementRef.nativeElement; //capture the HTML
element host
}
//Used to bind data: eg: <div [mathText]="raw string">
#Input('mathText') inputString:string;
// host element
private hostEl:HTMLElement;
//have MathJax parse the host element and render the math
render(){MathJax.Hub.Queue(['Typeset', MathJax.Hub, this.hostEl])}
// called when the inputString changes.
ngOnChanges(){
//make the input string into the innerText of the host element
this.hostEl.innerText = this.inputString;
this.render();
}
}
Register this directive in app.module.ts
and use this directive in html like:
<div [mathText]="\frac{a}{b}"></div>

PhoneGap Conversion - HTML to .apk

I am turning a HTML app into a .apk using https://build.phonegap.com and everything works great appart from my file selector.
<input name="file" type="file" id="file">
I want to be able to select images only (it doesnt matter if it can select more - but its the images I am looking for) from both camera and file system..
In the web version http://carbonyzed.co.uk/websites/assent/1/photos.html this works great from my phone, but when converted to .apk, this functionality is lost, and I can't seem to find anything on here, or online relating to this issue.
At least for me, the input file doesn't work in Phonegap.
You need use the Phonegap API to get picture and select the source where come from, like photolibrary, camera or savedphotoalbum.
See more info about camera.getPicture: http://docs.phonegap.com/en/2.1.0/cordova_camera_camera.md.html#camera.getPicture
and about Camera.PictureSourceType parameter of cameraOptions method: http://docs.phonegap.com/en/2.1.0/cordova_camera_camera.md.html#cameraOptions
Ended up using the Child Browser system like so
In the head
<script src="childbrowser.js"></script>
in the body
<button class="button-big" onClick="window.plugins.childBrowser.showWebPage('URL_TO_GO_HERE',
{ showAddress: false });" style="width: 100%;">UPLOAD PHOTOS</button>
which has a standard fileuploader like
<input name="file" type="file" id="file">
then it let me select from root storage, works in phonegap 2.2 onwards on both iOS and Android OS
To capture an image I used this in the head
<script type="text/javascript" charset="utf-8" src="json2.js"></script>
<script type="text/javascript" charset="utf-8">
// Called when capture operation is finished
//
function captureSuccess(mediaFiles) {
var i, len;
for (i = 0, len = mediaFiles.length; i < len; i += 1) {
uploadFile(mediaFiles[i]);
}
}
// Called if something bad happens.
//
function captureError(error) {
var msg = 'An error occurred during capture: ' + error.code;
navigator.notification.alert(msg, null, 'Uh oh!');
}
// A button will call this function
//
function captureImage() {
// Launch device camera application,
// allowing user to capture up to 2 images
navigator.device.capture.captureImage(captureSuccess, captureError, {limit: 2});
}
// Upload files to server
function uploadFile(mediaFile) {
var ft = new FileTransfer(),
path = mediaFile.fullPath,
name = mediaFile.name;
ft.upload(path,
"http://my.domain.com/upload.php",
function(result) {
console.log('Upload success: ' + result.responseCode);
console.log(result.bytesSent + ' bytes sent');
},
function(error) {
console.log('Error uploading file ' + path + ': ' + error.code);
},
{ fileName: name });
}
</script>
and this in the body
<input type="button" class="button-big" style="width: 100%;" onclick="captureImage();" value="TAKE PHOTO">
copy and past and it works a dream,
Check it out in this image
any questions, just email comment,
or email me... support#carbonyzed.co.uk

How can I load an image onto the HTML5 Canvas using Phonegap

Trying to load an image into onto an html5 canvas and then running the html5 on Android using Phonegap. Here is my HTML.
<!DOCTYPE HTML>
<html>
<body>
<canvas id="myCanvas" width="200" height="100" style="border:1px solid #c3c3c3;">
Your browser does not support the canvas element.
</canvas>
<script type="text/javascript">
var c=document.getElementById("myCanvas");
var cxt=c.getContext("2d");
var img=new Image()
img.src="img_flwr.png"
cxt.drawImage(img,0,0);
</script>
<img src="img_flwr.png"/>
</body>
</html>
I have included the standard img tag to demonstrate the problem.
Under Firefox, this page correctly shows the image rendered on the canvas and in the standard img tag.
When I deploy to Android emulator using Phonegap, only the standard img displays the picture.
Both the html and the .png file are in the assets/www folder of my phonegap project.
How can I get the image to render correctly on the canvas?
EDIT.. Fixed (thanks Avinash).. its all about timing.. you need to wait until the img is loaded before drawing onto the canvas ..vis
var c=document.getElementById("myCanvas");
var cxt=c.getContext("2d");
var img=new Image()
img.src="img_flwr.png";
img.onload = function() {
cxt.drawImage(img,0,0);
};
It might be the delay in loading the image(it's just a Guess of mine, I'm not sure. If it helps I'll be Glad) ...
Try this code(which waits until the page is loaded completely)
<!DOCTYPE HTML>
<html>
<body>
<canvas id="myCanvas" width="200" height="100" style="border:1px solid #c3c3c3;">
Your browser does not support the canvas element.
</canvas>
<script type="text/javascript">
window.onload = function() {
var c=document.getElementById('myCanvas');
var cxt=c.getContext('2d');
var img=new Image();
img.src='img_flwr.png';
cxt.drawImage(img,0,0);
};
</script>
<img src="img_flwr.png"/>
</body>
</html>
Or you can do after the Image is loaded as follows
var c=document.getElementById('myCanvas');
var cxt=c.getContext('2d');
var img=new Image();
img.onload = function() {
cxt.drawImage(img,0,0);
};
img.src='img_flwr.png';
Please let me know if the problem still persists ...
I haven't had a chance to try this but try to refer to your image as:
file://android_asset/www/img_flwr.png
I tried without the img tags for PhoneGap 1.1.0 Xcode 4.2 and the Image() class onload events fire but the images report zero widths and heights. If the img html tags are added they work. So I am thinking device ready is not a place to do this or this shows an incompatibility with how a js programmer might expect the events and sequencing to work. Having the images floating around off screen open issues with multiple resolutions.
Here is the stub code.
var tileLoaded = true;
var dirtLoaded = true;
function onBodyLoad()
{
document.addEventListener("deviceready", onDeviceReady, false);
}
/* When this function is called, PhoneGap has been initialized and is ready to roll */
/* If you are supporting your own protocol, the var invokeString will contain any arguments to the app launch.
see http://iosdevelopertips.com/cocoa/launching-your-own-application-via-a-custom-url-scheme.html
for more details -jm */
function onDeviceReady()
{
// do your thing!
//navigator.notification.alert("PhoneGap is working");
console.log("device on ready started");
canvas = document.getElementById('myCanvas');
c = canvas.getContext('2d');
canvas.addEventListener('mousedown', handleMouseDown, false);
window.addEventListener('keydown', handleKeyDown, false);
tileMap = [];
tile.src = "img/tile.png";
//tile.onLoad = tileImageLoaded();
dirt.src = "img/dirt.png";
//dirt.onLoad = dirtImageLoaded();
console.log("device on ready ended");
draw();
}
function tileImageLoaded()
{
console.log("tile loaded");
console.log("draw - tile.width:" + tile.width);
console.log("draw - tile.height:" + tile.height);
tileLoaded = true;
draw();
}
function dirtImageLoaded()
{
console.log("dirt loaded");
console.log("draw - dirt.width:" + dirt.width);
console.log("draw - dirt.height:" + dirt.height);
dirtLoaded = true;
draw();
}

Categories

Resources