Canvas not updating after camera used (Android / Ionic) - ionic-framework

I am trying to draw a scaled photo onto a canvas. However, the canvas will not update after I use the camera object to take the photo. Here's my camera code:
public openCamera() {
// do we have permission to access the camera?
this.androidPermissions.checkPermission(this.androidPermissions.PERMISSION.CAMERA).then(
result => console.log('openCamera > has camera permission: ', result.hasPermission),
err => this.androidPermissions.requestPermission(this.androidPermissions.PERMISSION.CAMERA)
);
this.androidPermissions.requestPermissions([this.androidPermissions.PERMISSION.CAMERA, this.androidPermissions.PERMISSION.GET_ACCOUNTS]);
const options: CameraOptions = {
quality: 100,
correctOrientation: true,
destinationType: this.camera.DestinationType.FILE_URI,
encodingType: this.camera.EncodingType.JPEG,
mediaType: this.camera.MediaType.PICTURE
}
let file_ext: string = null;
if (options.encodingType == EncodingType.JPEG) {
file_ext = "jpg";
console.log("openCamera > file_ext: ", file_ext);
}
else if (options.encodingType == EncodingType.PNG) {
file_ext = "png";
console.log("openCamera > file_ext: ", file_ext);
}
else {
this.presentAlert("Warning", "Unsupported image encoding type.");
return;
}
// photo already taken?
if (this.photo == null) {
this.photo = new Photo();
this.photo.id = Guid.create().toString();
this.photo.file_extension = file_ext;
}
// image filename: image_id.jpg
const dt: Date = new Date();
let dt_day: string = dt.getDate().toString();
dt_day = dt_day.length == 1 ? "0" + dt_day : dt_day;
let dt_month: string = (dt.getMonth() + 1).toString();
dt_month = dt_month.length == 1 ? "0" + dt_month : dt_month;
const dt_string: string = dt_day + "/" +
dt_month + "/" +
dt.getFullYear() + ", " +
dt.getHours() + ":" +
dt.getMinutes() + ":" +
dt.getSeconds() + "." +
dt.getMilliseconds();
if (this.photo.id == null || this.photo.id == '' || this.photo.id.length == 0) {
this.presentAlert("Error", "image id not set");
return;
}
else if (this.user.id == null || this.user.id == Guid.EMPTY || this.user.id == '' || this.user.id.length == 0) {
this.presentAlert("Error", "user.id not set");
return;
}
else if (dt_string == null || dt_string == '' || dt_string.length == 0) {
this.presentAlert("Error", "dt_string not set");
return;
}
this.photo.taken = dt_string;
const fileName: string = this.photo.id + ".jpg";
this.camera.getPicture(options).then((imageData) => {
// delete previous image
this.filePath.resolveNativePath(imageData)
.then((path) => {
let imagePath = path.substr(0, path.lastIndexOf("/") + 1);
let imageName = path.substring(path.lastIndexOf("/") + 1, path.length);
this.file.moveFile(imagePath, imageName, this.file.dataDirectory, fileName)
.then(newFile => {
this.ngZone.run(() => this.info = "Tap 'Upload' to upload photo");
this.db.addOrUpdatePhoto(this.photo)
.then(() => this.updateCanvas());
})
.catch(err => {
console.log("openCamera: ", err);
})
})
.catch((err) => {
console.log("openCamera: ", err);
})
})
.catch((err) => {
console.log("openCamera: ", err);
});
}
In the process of debugging this, I wrote a method to check that the photo actually exists after the camera has saved the image:
public exists() {
try {
this.file.listDir(this.file.dataDirectory, '')
.then(files => {
for (let i = 0; i < files.length; i++) {
if (files[i].name.includes(this.photo.id)) {
files[i].getMetadata((metadata) => {
this.presentAlert("image found", "filename: " + files[i].name + ", size: " + metadata.size + " bytes")
.then(() => this.updateCanvas());
});
}
}
});
}
catch { }
}
And I noticed that displaying an ionic alert before calling updateCanvas causes the photo to be correctly displayed onto the canvas. Does anyone know what the issue might be here?
Also, not sure if relevant, but I am using cordova-plugin-ionic-webview 4.1.1

I managed to solve this - the problem was the device itself. I tested on another phone and my canvas code worked perfectly. Uninstalling my app and reinstalling it did not resolve the issue, but a factory reset did. The device in question is an Honor 10 Lite. Not sure how this could have happened, maybe the device's WebView became corrupt somehow?

Related

LootLocker - How to show local rank

In my game, I am able to show the GlobalRank, however, I would also like to show the position of a player in Ranking according to the global results.
So in the bottom line, there should be the local (on this device) results.
Basically, on the left bottom corner, I want to get the RANK from the LootLocker, but I am struggling to get the rank...
IEnumerator ShowScores()
{
yield return new WaitForSeconds(2);
LootLockerSDKManager.GetScoreList(ID, maxScores, (response) =>
{
if (response.success)
{
LootLockerLeaderboardMember[] scores = response.items;
for (int i = 0; i < scores.Length; i++)
{
playerNames[i].text = (scores[i].member_id +"");
playerScores[i].text = (scores[i].score +"");
playerRank[i].text = (scores[i].rank + "");
//Rank of the localPlayer
Rank.text = (scores["here_Should_Be_This_Player_ID"].rank + "");
LootLockerSDKManager.GetPlayerName
// Entries[i].text = (scores[i].rank + ". " + scores[i].score + ". " + scores[i].member_id);
}
if (scores.Length < maxScores)
{
for (int i = scores.Length; i < maxScores; i++)
{
// Entries[i].text = (i + 1).ToString() + ". none";
}
}
}
else
{
}
});
}
Fixed it with the LootLocker support team
Step 1 - load LootLocker and get the resonse
Step 2 - load the rank and get the resonse2
Step 3 - use the "Response2.rank from the LootLocker
Rank.text = (response2.rank + "");
string playerIdentifier = "PlayerNameRecordOnThisDevice";
LootLockerSDKManager.StartSession(playerIdentifier, (response) =>
{
if (response.success)
{
Debug.Log("session with LootLocker started");
}
else
{
Debug.Log("failed to start sessions" + response.Error);
}
LootLockerSDKManager.GetMemberRank(ID, playerIdentifier, (response2) =>
{
if (response2.statusCode == 200)
{
Debug.Log("GetMemberRank Successful");
}
else
{
Debug.Log("GetMemberRank failed: " + response2.Error);
}
Rank.text = (response2.rank + "");
});
}); ```

I cannot get the html doc to load the javascript to make my calculator working

I've followed this calculator video on YouTube. I have 3 files in a folder .html, .css & .js.
I open the calculator by double-clicking the HTML file which seems to load up fine in opera with the CSS changing the appearance, however the functionality of the buttons do not work at all. Now I have double-checked the code and even gone as far as cheating with the resource material to be sure it's not an error in the code. I feel that the JavaScript isn't being read/used at all when it loads up.
https://www.youtube.com/watch?v=j59qQ7YWLxw
class calculator {
constructor(perviousOperandTextElement, currentOperandTextElement) {
this.perviousOperandTextElement = perviousOperandTextElement
this.currentOperandTextElement = currentOperandTextElement
this.clear()
}
clear() {
this.currentOperand = ''
this.perviousOperand = ''
this.operation = undefined
}
delete() {
this.currentOperand = this.currentOperand.toString().slice(0, -1)
}
appendNumber(number) {
if (number === '.' && this.currentOperand.includes('.')) return
this.currentOperand = this.currentOperand.toString() + number.tostring()
}
chooseOperation(operation) {
if (this.currentOperand === '') return
if (this.perviousOperand !== '') {
this.compute()
}
this.operation = operation
this.perviousOperand = this.currentOperand
this.currentOperand = ''
}
compute() {
let computation
const prev = parseFloat(this.previousOperand)
const current = parseFloat(this.currentOperand)
if (isNaN(prev) || isNaN(current)) return
switch (this.operation) {
case'+':
computation = prev + current
break
case '-':
computation = prev - current
break
case '*':
computation = prev * current
break
case 'รท':
computation = prev / current
break
default:
return
}
this.currentOperand = computation
this.operation = undefined
this.perviousOperand = ''
}
getDisplayNumber(number) {
const stringNumber = number.toString()
const integerDigits = parseFloat(stringNumber.split('.')[0])
const decimalDigits = stringNumber.split('.')[1]
let integerDisplay
if (isNaN(integerDigits)) {
integerDisplay = ''
} else {
integerDisplay integerDigits.toLocaleString('en', { maximumFractionDigits: 0 })
}
if (decimalDigits != null) {
return `${integerDisplay}.${decimalDigits}`
} else {
return integerDisplay
}
}
updateDisplay() {
this.currentOperandTextElement.innerText =
this.getDisplayNumber(this.currentOperand)
if (this.operation != null) {
this.previousOperandTextElement.innerText =
`${this.getDisplayNumber(this.perviousOperand)} ${this.operation}`
} else {
this.previousOperandTextElement.innerText = ''
}
}
}
const numberButtons = document.querySelectorAll('[data-number]')
const operationButtons = document.querySelectorAll('[data-operation]')
const equalsButton = document.querySelector('[data-equals]')
const deleteButton = document.querySelector('[data-delete]')
const allClearButton = document.querySelector('[data-all-clear]')
const previousOperandTextElement = document.querySelector('[data-previous-operand]')
const currentOperandTextElement = document.querySelector('[data-current-operand]')
const calculator = new calculator(previousOperandTextElement, currentOperandTextElement)
numberButtons.forEach(button => {
button.addEventListener('click', () => {
calculator.appendNumber(button.innerText)
calculator.updateDisplay()
})
})
operationButtons.forEach(button => {
button.addEventListener('click', () => {
calculator.chooseOperation(button.innerText)
calculator.updateDisplay()
})
})
equalsButton.addEventListener('click', button => {
calculator.compute()
calculator.updateDisplay()
})
allClearButton.addEventListener('click', button => {
calculator.clear()
calculator.updateDisplay()
})
deleteButton.addEventListener('click', button => {
calculator.delete()
calculator.updateDisplay()
})
Your javascript code is wrong at line 67.
We can see that at line 67, your code writes
integerDisplay integerDigits.toLocaleString('en', { maximumFractionDigits: 0 })
This is clearly wrong as you are missing a =, which assigns the value. A solution to this is to replace the line with
integerDisplay = integerDigits.toLocaleString('en', { maximumFractionDigits: 0 })

Firebase fetch inside for loop not working properly

In my project, I took data from the android accessibility stream in a headless background function turned them into an array and split them into chunks for firebase limits, and used a for loop to iterate over them and check in firebase. Sometimes this is not working, especially since I can see the associability service runner but showing data from a bit ago. I think this happens when the user is offline and tried to fetch data from firebase. Can you please have a look at this code and tell me what the issue is and How I should solve it?
N.B: I changed some variable names for privacy purposes. There are no issues with them.
FlutterAccessibilityService.accessStream.listen((event) {
if (event.capturedText != null &&
event.capturedText != "" &&
isCold) {
text = event.capturedText!.toLowerCase();
List textList = getArray(text);
final sharedItems = getSimilarArray(fbtag, textList, sensitivity);
final sharedLocalItems =
getSimilarLocalArray(fbtag, textList, sensitivity);
final sharedAbsItems = getAbsLocalArray(fbtag, textList);
final sharedItemWithLastEval =
getSimilarArray(lastEvaluatedText, textList, sensitivity);
if (text != lastEventText &&
(sharedItemWithLastEval.length == 0 ||
lastEvaluatedText[0] == "first")) {
print("called related content");
print("bg currant text: " +
text.toString() +
" sensitivity: " +
sensitivity.toString() +
" minimumAbsMatch: " +
minimumAbsMatch.toString() +
" shared local items: " +
sharedLocalItems.toString() +
" shared abs items: " +
sharedAbsItems.toString() +
" shared items: " +
sharedItems.toString() +
" last : " +
lastEventText +
" last eval text: " +
lastEvaluatedText.toString() +
" Cold: " +
isCold.toString());
print("captured text: " + text.toString());
//GetRelatedContent(fbtag, event.capturedText);
print(sharedItems);
if (sharedLocalItems.length >= accuracy &&
sharedAbsItems.length >= minimumAbsMatch) {
print("main called");
List result = [];
lastEvaluatedText = sharedItems;
List chunkedList = chunking(sharedItems);
for (int i = 0; i < chunkedList.length; i++) {
FirebaseFirestore.instance
.collection('Content')
.where('keyWords', arrayContainsAny: chunkedList[i])
.get()
.then((value) {
for (int i = 0; i < value.docs.length; i++) {
result.add(value.docs[i].data());
print("sep");
print("result: " + result.toString());
}
if (i == chunkedList.length - 1) {
if (result.isNotEmpty) {
print("final result: " +
result[HighestMatchingIndex(sharedItems, result)[0]]
.toString());
print('result length called' +
' result: ' +
result.toString());
if (HighestMatchingIndex(sharedItems, result)[1] >=
accuracy) {
print('overlay called');
isCold = false;
Timer(Duration(seconds: 60), () {
print("Cold down");
isCold = true;
});
var FinalResult = result[
HighestMatchingIndex(sharedItems, result)[0]];
if (FinalResult['availableCountry']
.contains(country) &&
FinalResult['availableR']
.contains(r)) {
print("all passed");
String l = FinalResult[r]
[country] ??
FinalResult[r]['EN'];
String o =
FinalResult[r]['origin'];
ShowAlert(l, o, r);
}
}
}
}
});
}
}
//
}
lastEventText = text;
}
});

Getting Error 413 when attach image in the http request to node server in ionic 3

I am working on App where it needs to upload up to 4 images with the other data (images are optional). While uploading multiple images with other data with Ionic Native HTTP request to the node server (APIs are created in nodejs) I am getting below error.
error:{"statusCode":413,"error":"Request Entity Too Large","message":"Payload content lenght greater than maximum allowed: 1048576"}
I have searched for the issue but didn't get solutions except this, but don't know how to apply it in my ionic 3 app.
This is my code.
openGallery(){
if (
this.thumb1 != "" &&
this.thumb2 != "" &&
this.thumb3 != "" &&
this.thumb4 != ""
) {
this.presentToast("You can not upload more than 4 images.");
return;
}
var options = {
sourceType: this.camera.PictureSourceType.PHOTOLIBRARY,
encodingType: this.camera.EncodingType.JPEG,
quality: 10,
destinationType: this.camera.DestinationType.DATA_URL
// destinationType: this.camera.DestinationType.FILE_URI
};
this.camera.getPicture(options).then(imageData => {
let base64File = "data:image/jpeg;base64," + imageData;
if (this.Image_0 === null) {
this.Image_0 = base64File;
} else if (this.Image_1 === null) {
this.Image_1 = base64File;
} else if (this.Image_2 === null) {
this.Image_2 = base64File;
} else if (this.Image_3 === null) {
this.Image_3 = base64File;
}
let base64Image = base64File;
if (this.thumb1 == "") {
this.thumb1 = base64Image;
this.thumb1 = this.sanitizer.bypassSecurityTrustResourceUrl(
this.thumb1
);
} else if (this.thumb2 == "") {
this.thumb2 = base64Image;
this.thumb2 = this.sanitizer.bypassSecurityTrustResourceUrl(
this.thumb2
);
} else if (this.thumb3 == "") {
this.thumb3 = base64Image;
this.thumb3 = this.sanitizer.bypassSecurityTrustResourceUrl(
this.thumb3
);
} else if (this.thumb4 == "") {
this.thumb4 = base64Image;
this.thumb4 = this.sanitizer.bypassSecurityTrustResourceUrl(
this.thumb4
);
}
}).catch(e => {
console.log("Error while picking from gallery", e);
});
}
postForm(){
let loading = this.loadingCtrl.create({
spinner: "bubbles"
});
loading.present();
let myData: any = {
Type: 1,
CustomerId: this.CustomerId,
Rating: Rating,
Review: this.review.value.comment
};
if (this.Image_0 != null) {
myData.Image_0 = this.Image_0;
}
if (this.Image_1 != null) {
myData.Image_1 = this.Image_1;
}
if (this.Image_2 != null) {
myData.Image_1 = this.Image_2;
}
if (this.Image_3 != null) {
myData.Image_3 = this.Image_3;
}
this.http
.post(
global.apiUrl + "restaurants/" + this._id + "/reviews",
myData,
headers
)
.then(data => {
})
.catch(error => {
loading.dismiss();
alert(JSON.stringify(error, Object.getOwnPropertyNames(error)));
});
}
I am trying to find the solution since last few days but couldn't find the solution so, therefore, posting here.
Update: We are using Hapi server.
I've managed to accomplish the image upload. The mistake is that I haven't specified the height and width of the image.
const options: CameraOptions = {
quality: 100,
destinationType: this.camera.DestinationType.FILE_URI,
mediaType: this.camera.MediaType.PICTURE,
targetWidth: 250,
targetHeight: 200,
correctOrientation: true
};

when I pushed the phone button to back previous page in Unity webviewScript

using System.Collections;
using UnityEngine;
using System;
using System.Collections.Generic;
public class SampleWebView : MonoBehaviour
{
public string Url;
public GUIText status;
WebViewObject webViewObject;
IEnumerator Start()
{
webViewObject = (new GameObject("WebViewObject")).AddComponent<WebViewObject>();
webViewObject.Init(
cb: (msg) =>
{
Debug.Log(string.Format("CallFromJS[{0}]", msg));
status.text = msg;
status.GetComponent<Animation>().Play();
},
err: (msg) =>
{
Debug.Log(string.Format("CallOnError[{0}]", msg));
status.text = msg;
status.GetComponent<Animation>().Play();
},
started: (msg) =>
{
Debug.Log(string.Format("CallOnStarted[{0}]", msg));
},
ld: (msg) =>
{
Debug.Log(string.Format("CallOnLoaded[{0}]", msg));
#if UNITY_EDITOR_OSX || !UNITY_ANDROID
// NOTE: depending on the situation, you might prefer
// the 'iframe' approach.
// cf. https://github.com/gree/unity-webview/issues/189
#if true
webViewObject.EvaluateJS(#"
if (window && window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.unityControl) {
window.Unity = {
call: function(msg) {
window.webkit.messageHandlers.unityControl.postMessage(msg);
}
}
} else {
window.Unity = {
call: function(msg) {
window.location = 'unity:' + msg;
}
}
}
");
#else
webViewObject.EvaluateJS(#"
if (window && window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.unityControl) {
window.Unity = {
call: function(msg) {
window.webkit.messageHandlers.unityControl.postMessage(msg);
}
}
} else {
window.Unity = {
call: function(msg) {
var iframe = document.createElement('IFRAME');
iframe.setAttribute('src', 'unity:' + msg);
document.documentElement.appendChild(iframe);
iframe.parentNode.removeChild(iframe);
iframe = null;
}
}
}
");
#endif
#endif
webViewObject.EvaluateJS(#"Unity.call('ua=' + navigator.userAgent)");
},
//ua: "custom user agent string",
enableWKWebView: true);
#if UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX
webViewObject.bitmapRefreshCycle = 1;
#endif
webViewObject.SetMargins(10, 140, 10, Screen.height / 360);
webViewObject.SetVisibility(true);
#if !UNITY_WEBPLAYER
if (Url.StartsWith("http")) {
webViewObject.LoadURL(Url.Replace(" ", "%20"));
} else {
var exts = new string[]{
".jpg",
".js",
".html" // should be last
};
foreach (var ext in exts) {
var url = Url.Replace(".html", ext);
var src = System.IO.Path.Combine(Application.streamingAssetsPath, url);
var dst = System.IO.Path.Combine(Application.persistentDataPath, url);
byte[] result = null;
if (src.Contains("://")) { // for Android
var www = new WWW(src);
yield return www;
result = www.bytes;
} else {
result = System.IO.File.ReadAllBytes(src);
}
System.IO.File.WriteAllBytes(dst, result);
if (ext == ".html") {
webViewObject.LoadURL("file://" + dst.Replace(" ", "%20"));
break;
}
}
}
#else
if (Url.StartsWith("http")) {
webViewObject.LoadURL(Url.Replace(" ", "%20"));
} else {
webViewObject.LoadURL("StreamingAssets/" + Url.Replace(" ", "%20"));
}
webViewObject.EvaluateJS(
"parent.$(function() {" +
" window.Unity = {" +
" call:function(msg) {" +
" parent.unityWebView.sendMessage('WebViewObject', msg)" +
" }" +
" };" +
"});");
#endif
yield break;
}
#if !UNITY_WEBPLAYER
//void OnGUI()
//{
// GUI.enabled = webViewObject.CanGoBack();
// if (GUI.Button(new Rect(10, 10, 80, 80), "<")) {
// webViewObject.GoBack();
// }
// GUI.enabled = true;
// GUI.enabled = webViewObject.CanGoForward();
// if (GUI.Button(new Rect(100, 10, 80, 80), ">")) {
// webViewObject.GoForward();
// }
// GUI.enabled = true;
// GUI.TextField(new Rect(200, 10, 300, 80), "" + webViewObject.Progress());
//}
#endif
This is my webview Scirpt for my newspaper App in C#. I need code, when I pushed the phone button to go back previous page in the newspaper.
I tried,
if(Input.GetKeyDown(KeyCode.Escape))
{
Application.Quit();
}
However it quits from the app. It does not go back previous page in the newspaper..
Thank you for your help...
if i understand it correctly you should be good if you replace
if(Input.GetKeyDown(KeyCode.Escape))
{
Application.Quit();
}
by this:
if(Input.GetKeyDown(KeyCode.Escape))
{
webViewObject.GoBack();
}
According to the example you are using from here https://github.com/gree/unity-webview/blob/master/sample/Assets/Scripts/SampleWebView.cs this is the build in back function. You can see it in the commented out part in your code.