The goal is to make an Android App that uses these features so I can then copy/paste the HTML and JavaScript code from this page into my actual Single Page Application and have a working Android App.
Use Android Studio to build an app that points to this page. Modify the JavaScript in this page so it interacts with Android phones to do each of these features. Project is completed when I can compile your finished project in my Android Studio and it works accessing this page. I’m using:
Android Studio Flamingo | 2022.2.1 Patch 2 Build #AI-222.4459.24.2221.10121639, built on May 12, 2023 Runtime version: 17.0.6+0-17.0.6b802.4-9586694 aarch64 VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o. macOS 13.4.1 GC: G1 Young Generation, G1 Old Generation Memory: 2048M Cores: 8 Metal Rendering is ON Registry: external.system.auto.import.disabled=true ide.text.editor.with.preview.show.floating.toolbar=false gradle.version.catalogs.dynamic.support=true
Our PWA/SPA uses MaterializeCSS and jQuery so code must be compatible with those libraries.
Debug code is shown in JS console and in right side of page on desktops/tablets or on bottom of page when viewed on phones.
We need to be able to use JavaScript to turn the microphone on and off. Once the user has given us permission to use the microphone, it should remember and not request permission again every time the app is started.
Mic On - Start Listening
Mic Off - Stop Listening
This code is working on iPhone when called from App but not when gone to directly in Chrome browser. In iPhone App the Speech to Text is quite good.
On Android it cuts the microphone off before done speaking so the code definitely needs to be changed. Use whatever Speech to Text works best - probably needs to access native phone features.
We use Google Text to Speech which creates MP3 files which we save on the server then the JS plays that MP3.
Use this page to verify the volume does not change after the microphone is used. Currently the JS below does not use native calls but can be changed to do so if necessary.
This will start by playing a ringing MP3, then it will play a greeting MP3. After that each time you click the "Play Next" button it will play the next MP3 in the list.
The current app does not need this feature but I would like to have it prototyped for future applications. Make this work and document how to add the permission request in Android Studio or remove the permission request when not needed. See wtkDialPhone in JavaScript code below.
We need native access to camera. This should allow user to either pick from their photo album or take a photo. The HTML and JS code in this page is what we used in prior iOS Xcode apps.
This is the most complicated because it requires five steps:
You only have to do steps 2, 3 and 5.
The takePhoto JS function below has two parameters. The first is a SQL table name and the second is the UID of the associated table row.
// JavaScript function
function takePhoto(fncTable, fncId) {
wtkDebugLog('takePhoto ' + pgAccessedBy + ': ' + fncTable + '; id = ' + fncId);
$('#photoProgressDIV').removeClass('hide');
switch(pgAccessedBy){
case 'ios':
window.ReactNativeWebView.postMessage('photo-' + fncTable + '-' + fncId);
break;
case 'android':
wtkDebugLog('takePhoto: code needs to be added here');
// the code should be similar to the iOS code and send to Android 'photo-' + fncTable + '-' + fncId
break;
case 'browser':
// not applicable because PHP will generate HTML file upload instead of takePhoto JS call
break;
} // switch
} // takePhoto
The PHP page that receives the posted file expects to receive it in the following manner so our code will work regardless whether called from iPhones or Android phones. If something needs to be changed for Android, let me know. Note: the PHP code is all written and working. If you want to work on this project PM me and I’ll send you the name and location of this file so you can test uploading to it.
<?php
$pgPostData = file_get_contents("php://input");
$pgJSON = json_decode($pgPostData, true);
$pgApiKey = $pgJSON['wtkApiKey']; // pass value of 'prototypeWTKApiKey' for validation
$pgTable = $pgJSON['table']; // fncTable value passed to takePhoto JS function
$pgId = $pgJSON['id']; // fncId value passed to takePhoto JS function
$pgFileName = $pgJSON['fileName']; // name of image file you are uploading
$pgFile = $pgJSON['fileData']; // base64 version of image file being uploaded
// ... validate API Key or lock out; $pgJSON['wtkApiKey'] better equal 'prototypeWTKApiKey'
// ... if valid save file to server and SQL database ...
$pgPath = '/image/test/'; // path will be based on table name and other logic
$pgFileName = wtkReplace($pgFileName, "'", '');
$pgFileName = wtkReplace($pgFileName, ' ', '');
$pgFileExt = pathinfo($pgFileName, PATHINFO_EXTENSION);
$pgFileArray = explode(',', $pgFile);
$pgFixedFile = $pgFileArray[1]; // gets rid of data:image/jpeg;base64,
$pgNewFileName = wtkGenerateFileName($pgTable, $pgFileExt); // returns something like 'user4770.png'
$pgUploadFile = '..' . $pgPath . $pgNewFileName;
$pgUploadFile = wtkReplace($pgUploadFile, '....', '../..');
$fp = fopen($pgUploadFile, 'w');
fwrite($fp, base64_decode($pgFixedFile) );
fclose($fp);
$pgJSON = '{"result":"success","path":"' . $pgPath . '","fileName":"' . $pgNewFileName . '"}';
echo $pgJSON;
exit;
?>
We have some "receiver" code written which works for iPhones. Modify as needed to make it work for Android.
// JavaScript code
// BEGIN Receiver to listen for Android sending of photo upload confirmation
const isUIWebView = () => {
return navigator.userAgent.toLowerCase().match(/\(.*applewebkit(?!.*(version|crios))/)
};
const receiver = isUIWebView() ? window : document;
receiver.addEventListener('message', data => {
receiveMessage(data);
});
// END Receiver to listen for Android sending of photo upload confirmation
Below that in the JavaScript of this page are also the receiveMessage and handleMessage functions but I expect those will not need to be changed.