Touch events on React component in Chrome not captured unless desktop version is opened first - android

I have a React website at blogtheworld.co which displays pins on a world map. On desktop, when the user hovers over a pin a react-bootstrap 'popover' appears with more details (the react-bootstrap OverlayTrigger listens for both 'hover' and 'focus' events):
Additionally, when the user right-clicks somewhere on the map, a context menu opens with the option to add a post.
The code repository is here for anyone who wants to see the details.
When I open the site in Chrome for Android, the mobile version does not respond to either tapping on the pin for details or long-pressing the map for the context menu. Other touch events (on the button for filters in the top-right, or on the location search bar) are captured:
Now, if I go to the Chrome menu and select 'Desktop site', the desktop site opens and touch events are detected. This in itself is not particularly surprising, but here's where things get really weird: if I subsequently go back to the mobile version of the site (by unchecking 'Desktop site' in Chrome), the touch events are now detected! I can tap on pins to open the popover:
Long-pressing to bring up the context menu also works.
Somehow, the process of switching from the mobile version to the desktop version and back to mobile 'tricks' Chrome into successfully detecting the events. Using developer tools to track the pointerDown events, I can see that there are #document.pointerDown and DIV.pointerDown events fired in both cases, but in the working version there are additional BODY.pointerDown events which are not fired in the non-working version. What I would like to know is, how can I modify my React code to enable the events to be detected by default?
Another important point to note: the site works fine on Firefox for Android and Safari for iOS.
EDIT (extra weirdness): when I run the production Docker container locally and access localhost:3000 from my phone via USB debugging, there is no problem. So this bug appears when the site is running on a DigitalOcean droplet, but not when exactly the same site is running on localhost. Obviously this is impossible, and yet it is the case.

Related

Make my Android app to fully kiosk mode when enabled

I am trying to make my feedback app to support fully kiosk, I have tried a lot of solutions but Nothing is completely satisfying my need. Here are the things that I found yet.
1. Make my app as Device Admin/Owner App(Lock Task) -
If we follow this link/procedure https://developer.android.com/work/dpc/dedicated-devices/lock-task-mode, some limitations are there as follows -
a. We have to factory reset all the devices where Feedback app is installed, follow some steps to make it as admin app(launcher app).
b. Installation of the app will be possible using the command line, each installation will take some line of code through cmd, which means for installing a person has to go there with the computer and connect the device with USB and then install the app using commands.
c. Update on an app will also follow the same procedure (Couldn't be performed using google play store)
d. In this case, end-user will never be able to exit from our app, restart the device would also launch the same feedback app every single time.
2. Programmatically screen pinning + programmatically volume and power button controlling. (https://github.com/mrugacz95/kiosk)
a. In this, we will make the app in screen pinning mode where all the three bottom buttons(Overview, home, recent) will be hidden/disabled. and same with the power key and volume keys.
b. So As soon user clicks on kiosk mode, a screen pinning system generated prompt would be shown to user But the biggest disadvantage of it is that app would be unpinned/unlocked as soon as the user presses overview+recent buttons together.
3. The third Case is, where all the keys are controlled including power+voulme+back+overview etc.
Only pressing home will make the app to go on the background and within seconds it will again come foreground.
So all I found up until now, is not very satisfiable.
One more Question-
Is this something to be fully controlled by MDM(Mobile Device Management)?
Any help is appreciated.
1. Make my app as Device Admin/Owner App
a. A device owner can only be installed on a newly initialized device (before an account is added). I believe this is by design : A device owner can completely lock the device down, you don't want a malicious app to be able to seize the phone of an unsuspecting user after a few "I agree" popups.
b. You don't need to install it using adb. The simplest provisioning method is via NFC : While the device shows the very first screen of the setup wizard, touch it with a tag (or another device) containing the provisioning configuration, most importantly an URL where the apk can be downloaded and a WiFi config.
Another method is via QR code (Android 7+) : tap 6 times the first setup screen. It is a bit less convenient than NFC because you usually have to provision the WiFi manually.
c. A device owner can be updated like any other app. As it can itself install or update applications without asking the user, you can implement a fully automatized self update mechanism : check for update / download / update.
2. Lock task / screen pinning
Any application can programatically enter lock task mode. How it happens depends on whether the application is white listed by a device owner app (possibly itself) :
If not, the user is prompted and must accept, they can also exit at any time. This is basically the same thing as screen pinning.
If yes, there is no popup : the user can not decline to enter, nor exit, the lock task mode.
Additionally a kiosk application can act as a launcher. A device owner (again, possibly itself) can set it without user intervention
Is this something to be fully controlled by MDM(Mobile Device Management)?
While device owner apps are usually DPC connected to a MDM console of some sort, this is not a technical requirement. How you control it is completely up to you. (I hope I understood correctly the question)
Overall, I think that the only reliable way a device can be locked in kiosk mode is to use a device owner app (separately or included in the kiosk application). The setup via NFC or QR code is actually faster than a normal device setup. It can also protect against safe mode reboot or factory reset. The only real constraint is that you can not deploy this kind of application on existing devices without wiping them first.
Make my app as Device Admin/Owner App(Lock Task) -
a. If you are making it an 'admin app' this means you have signed the device image correct? Therefore you control the full flashing of the device - you can do anything in this scenario.
b. You can actually also do ADB over WiFi after you set it up the first time
c. You can update your apps from the playstore - even launcher applications
d. This fact is the whole point of Kiosk mode. Users should not ever be able to exit the application. Only you can exit, either with a remote command or with a invisible touch combination (for example touching each of the corners of the screen in sequence twice, or other 'secret unlock code')
Programmatically screen pinning + programmatically volume and power button controlling. (https://github.com/mrugacz95/kiosk)
b. This is the opposite of 1d, it is not clear what you want if you want neither.
The third Case is, where all the keys are controlled including power+voulme+back+overview etc.
This is also the opposite of 1d, it is not clear what you want if you want neither.
We need a few more details on your deployment scenario for this app to help you out further.

Android WebView: where are connections to bc.googleusercontent.com coming from?

My app opens a WebView, which in turn loads a simple page from my remote host. Recently I've been trying to minimise the amount of data usage, by maximising cache usage, and have started using a network connections monitor app like this and this to check what connections are actually being made by my app (and others).
These are showing that, as well as a connection being made to the host when the webview loads, a connection is also being made to nnn.n.nnn.nn.bc.googleusercontent.com. The first of the above apps resolves this to an admin address of Google Inc.
But I have no idea why this connection is being made. My webpage does not have any google-related tracking code or anything like that, has no links to adverts, nothing at all along those lines. And the Android app itself, that loads the WebView, likewise does not at any point try to fetch "user content" from googleusercontent.com.
I would post some code, but since I have no idea where this call is initiated from, I wouldn't know what to show. I would also say that I have noticed on my phone that occasionally a full-page advert will pop up, and I have no idea where it's coming from... but it doesn't happen at the same time as these calls to googleusercontent.com.
Any insight on this would be most welcome.
OK I think I figured it out. My web page makes a call to my node.js app running on Cloud 9... I think that the mysterious nnn.n.nnn.nn.bc.googleusercontent.com must just be where the node app is being hosted. When I call this page from my production app (where the node app is running on heroku) I get a call to a different yet similarly mysterious-looking address: xxxxxxx.eu-west-1.compute.amazonaws.com... so that must be where the heroku node app is hosted.

Cordova InAppBrowser opens double window on Android

I have developed an app in Cordova 3.6 with latest version of InAppBrowser. Run on Android device (4.1.2 and others) when the user taps a link to open InAppBrowser, occasionally a double window seems to open up. The second of these windows doesn't close.
To check if it was something I had done in my app, I quickly created a default Cordova hello world app and added the standard window.open code with link like this
OPEN WINDOW
and basic testing on the device revealed the same thing was happening - occasionally fast or double tapping made a double window open up, one of which was uncloseable. Either from <300ms double tap, or from double taps where the browser is slow to launch.
This doesn't appear to happen on iOS.
Any help gratefully appreciated.
UPDATE
Part of the problem on my main app was functions declared in wrong place (onpagecreate) being fired multiple times. I put this here in case someone does anything similar...
However on the hello world app the problem still occasionally happens. I tried with and without Fastclick, but Fastclick didn't work properly (possible conflict with jQuery Mobile, arrghh).
your problem is likely caused by using the 'onclick' event to launch the childbrowser.
onclick has a built in 300ms timeout, which can make an app appear laggy and causes some of the issues above.
Use mouseup/mousedown instead, and inside the handler, disable the listener
OPEN WINDOW
function open(url, name) {
// deregister the onclick listener, insuring the callback resolves
window.open(url,name);
// register the listener
}

Set mouse position in software

I am using an Android Stick (http://www.geekbuying.com/item/Uhost-2-Dual-Core-TV-Box-Mini-PC-Android-4-0-4-RK3066-Cortex-A9-1-6GHZ-1GB-RAM-4G-ROM-with-Bluetooth-WIFI-Skype-XBMC---Black-312467.html) for building an application. The application uses an attached USB webcam for some of it's functionality. Additionally, I connect a mouse to this device which the user can use to navigate through various pages in the application. A left/right movement of the mouse results in navigation to previous/next page.
While the mouse works with the Android device, I additionally require to reset the position of the mouse to the center after every single interaction with the user. Is it possible to set the mouse position using software in Android? I am using View.OnGenericMotionListener to capture the mouse movement.
Currently, I also require to perform a primary mouse button click to bring the mouse in focus inside the application. I want to remove this requirement by either generating the primary mouse button click in software, or otherwise bring the application in software by some other means.
I have been unable to find any APIs to get the above to work. Any help on these would be greatly useful.
Just in case I need to write some sort of drivers to get this thing working, any help in this direction would also be useful.
Any workarounds around this problem, while still using the mouse, could also prove useful.
Mouse event is managed by the system framework. You cannot control it on Java side.
On the adb shell you can open /dev/input/uevent device to write mouse events include
relative movement
click action
absolute position (you might want this)
However, you cannot do it as a normal application, unless you do it on a rooted device, or you can use adb shell to start a daemon service in the background to perform the event writing for your application.
I additionally require to reset the position of the mouse to the center after every single interaction with the user.
This is now possible with the pointer capture API in Android 8.0+ (released August 2017). Summary:
To request pointer capture, call the requestPointerCapture() method on the view.
Once the request to capture the pointer is successful, Android calls onPointerCaptureChange(true), and starts delivering the mouse events.
Your focused view can handle the events by performing one of the following tasks:
If you're using a custom view, override onCapturedPointerEvent(MotionEvent).
Otherwise, register an OnCapturedPointerListener.
The view in your app can release the pointer capture by calling releasePointerCapture().

Check if web app is added to home screen on Android

I have a web app and on the Android I would like to display an alert describing how to add my app to the home screen. (Add it to "Bookmarks" and then "Add it to home screen" or "Add to shortcut in Home"). Then a icon will be displayed on the screen that opens my app.
But off course I only want this to show if the app is not added to the home screen.
Does anybody know how to do this?
Any input appreciated, thanks.
Yes, you can.
While technically a page open in Chrome browser tab can't directly check whether a home screen shortcut exists, the page's local data (localStorage, IndexedDB) is shared between home screen instance and browser tabs, so this can be used to communicate the existence of the home screen version.
Detect if the app is running from home screen
If it's ran from home screen, save this fact to localStorage
Profit! (by reading this from localStorage in any tab)
When the app is in standalone view (which is possible only when launched from home screen), the CSS media query (display-mode: standalone) will match. In Javascript you can read it using:
matchMedia('(display-mode: standalone)').matches
(BTW: the non-standard iOS equivalent of this is navigator.standalone, but iOS doesn't share state between home screen and Safari, so you're out of luck there).
However, instead of custom instructions I suggest meeting Chrome's criteria for "progressive web app" and let Chrome do the prompting for you.
You can't check a web app if its added to home screen on android. At least for now. (Chrome 67)
But you can tell if the app is running in standalone mode using display-mode media query.
Add this inside your <style> tag.
#media all and (display-mode: standalone) {
body {
background-color: yellow;
}
}
Then in your <script> tag.
if (window.matchMedia('(display-mode: standalone)').matches) {
console.log('display-mode is standalone');
}
Or this
if (window.navigator.standalone === true) {
console.log('display-mode is standalone');
}
You can check more from here.
The short answer is: from a Web Site you can't.
The longer answer is: from a Web site you might be able to get a hint in Chrome.
Chrome on Android two new features 1) Web App Manifest that describes what should be launched from the home screen and how it should look on the homescreen, and 2) Chrome now has an beforeinstallprompt event that will trigger for Web apps that we think are app-like and can be installed to the homescreen.
There are a number of criteria for the onbeforeinstallprompt event to fire which might make it an "ok" heuristic (although I suspect not).
The event only fires if:
The site has a manifest, is on https and has a service worker. (this can be quite a stretch).
The user has engaged with the site multiple times (right now, twice within at least 5 minutes).
The user has not already added your site to the home-screen.
So, in summary it is complex and full of false positives and false negatives. However if all you want to do is detect if you should display a banner to prompt the user to add your web-app to the homescreen then Chrome already has a solution for you.
We also have a full range of samples on our samples site.
I think you can do it. Simply add query string to start_url in manifest.json and in your javascript check if start url is having that query string. If query string is found then yeah app is installed.
first you get the list of apps on the device
List<ApplicationInfo> packs = pm.getInstalledApplications(0);
then you use getLaunchIntentForPackage()
Now that you've got the list of packages installed on your device,
iterate through them and call getLaunchIntentForPackage() on each
item.
If a valid intent is returned, it exists on the Launcher, else if null
is returned, the package does not launch from the Launcher screen.
Note that Home screen shortcuts are a subset of the Launcher apps.

Categories

Resources