I'm developing a cross platform app using cordova with an angular material front end.
I use HTML5 video tags in a list of md-cards to play videos with external urls. When inline the videos play correctly, and display the native controls as expected.
<video class="project-video" video-directive item="$ctrl.project" ng-src="{{$ctrl.project.videoUrl | trustUrl}}" preload="auto"
controls poster="{{$ctrl.project.video.thumbnail_url}}">
Your browser does not support the video tag.
</video>
However when I click the "toggle full-screen" button the video does go to full-screen, but the default controls disappear. I cannot get back to the app after this - the native android back button does not close the full screen - instead it closes the whole app.
The solution I am looking for will make the controls always appear even in full screen mode; this works out the box running the same code on iOS.
Therefore I do not want to spend time developing my own custom video controls just for android, if I can help it! So please do not post answers about how to do that (plenty already available on SO and elsewhere).
I am using a Meizu m2 note android device.
Thanks!
EDIT:
The controls are still there but are showing up in the shadow DOM tree in css as being of size 0 x 0px. Even when I change their size in chrome dev tools using the !important flag, they do not show up.
Any ideas?
This is an issue with Flyme OS which is used by Meizu devices. Since the controls are available and not visible, this should be resolved by ugrading the Flyme OS.
Please update Flyme OS to resolve this as the older versions of Flyme seems to have quiet some problems with fullscreen video mode. Hope it helps. Cheers
set the values which then allow to exit fullscreen.
var videoElement = document.getElementById("myvideo");
function toggleFullScreen() {
if (!document.mozFullScreen && !document.webkitFullScreen) {
if (videoElement.mozRequestFullScreen) {
videoElement.mozRequestFullScreen();
} else {
videoElement.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT);
}
document.mozFullScreen = true;
document.webkitFullScreen = true;
} else {
if (document.mozCancelFullScreen) {
document.mozCancelFullScreen();
} else {
document.webkitCancelFullScreen();
}
}
}
document.addEventListener("keydown", function(e) {
if (e.keyCode == 13) {
toggleFullScreen();
}
}, false);
add these two lines ..
document.mozFullScreen = true;
document.webkitFullScreen = true;
if you want something better
fullScreenButton.addEventListener("click", function() {
if (!document.fullscreenElement && // alternative standard method
!document.mozFullScreenElement && !document.webkitFullscreenElement && !document.msFullscreenElement ) { // current working methods
if (video.requestFullscreen) {
video.requestFullscreen();
} else if (video.msRequestFullscreen) {
video.msRequestFullscreen();
} else if (video.mozRequestFullScreen) {
video.mozRequestFullScreen();
} else if (video.webkitRequestFullscreen) {
video.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
}
} else {
if (document.exitFullscreen) {
document.exitFullscreen();
} else if (document.msExitFullscreen) {
document.msExitFullscreen();
} else if (document.mozCancelFullScreen) {
document.mozCancelFullScreen();
} else if (document.webkitExitFullscreen) {
document.webkitExitFullscreen();
}
}
});
How about this in your code your not mentioned controls attribute fully may be that could cause the problem
<video id="myvideo">
<source src="path/to/movie.mp4" />
</video>
<p onclick="toggleControls();">Toggle</p>
<script>
var video = document.getElementById("myvideo");
function toggleControls() {
if (video.hasAttribute("controls")) {
video.removeAttribute("controls")
} else {
video.setAttribute("controls","controls")
}
}
</script>
Related
How can I set the display to stereoscopic programmatically in Unity for an app deployed to an Android device?
I want a UI menu where the user can toggle between "VR mode" and normal mode. I do not want VR mode by default as it should be an option at run-time. I know there is a setting for "Virtual Reality Supported" in the build settings, but again, I do not want this enabled by default.
Include using UnityEngine.XR; at the top.
Call XRSettings.LoadDeviceByName("") with empty string followed by XRSettings.enabled = false; to disable VR in the start function to disable VR.
When you want to enable it later on, call XRSettings.LoadDeviceByName("daydream") with the VR name followed by XRSettings.enabled = true;.
You should wait for a frame between each function call. That requires this to be done a corutine function.
Also, On some VR devices, you must go to Edit->Project Settings->Player and make sure that Virtual Reality Supported check-box is checked(true) before this will work. Then you can disable it in the Start function and enable it whenever you want.
EDIT:
This is known to work on some VR devices and not all VR devices. Although, it should work on Daydream VR. Complete code sample:
IEnumerator LoadDevice(string newDevice, bool enable)
{
XRSettings.LoadDeviceByName(newDevice);
yield return null;
XRSettings.enabled = enable;
}
void EnableVR()
{
StartCoroutine(LoadDevice("daydream", true));
}
void DisableVR()
{
StartCoroutine(LoadDevice("", false));
}
Call EnableVR() to enable vr and DisableVR() to disable it. If you are using anything other than daydream, pass the name of that VR device to the LoadDevice function in the EnableVR() function.
For newer builds of Unity (e.g. 2019.4.0f1) you can use the XR Plugin Management package.
To enable call:
XRGeneralSettings.Instance.Manager.InitializeLoader();
To disable call:
XRGeneralSettings.Instance.Manager.DeinitializeLoader();
I'm using Unity 2021 but this probably works in earlier versions, I'm also using XR Plug-in Management.
Start:
XRGeneralSettings.Instance.Manager.StartSubsystems();
Stop:
XRGeneralSettings.Instance.Manager.StopSubsystems();
Full documentation at:
https://docs.unity3d.com/Packages/com.unity.xr.management#4.0/manual/EndUser.html
2020.3.14f1
Doesn't work for me, I get this error when running my Android app.
Call to DeinitializeLoader without an initialized manager.Please make
sure wait for initialization to complete before calling this API.
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterAssembliesLoaded)]
static void TryToDeinitializeOculusLoader()
{
XRGeneralSettings.Instance.Manager.DeinitializeLoader();
}
More context.
I try to unload the Oculus loader, before he manages to load the plugin.
I have an Android app, and the Oculus loader calls Application.Quit because the device is not an Oculus headset.
Waiting for XRGeneralSettings.Instance.Manager.isInitializationComplete takes too long.
Tried all RuntimeInitializeLoadType annotations.
OculusLoader.cs
#elif (UNITY_ANDROID && !UNITY_EDITOR)
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterAssembliesLoaded)]
static void RuntimeLoadOVRPlugin()
{
var supported = IsDeviceSupported();
if (supported == DeviceSupportedResult.ExitApplication)
{
Debug.LogError("\n\nExiting application:\n\nThis .apk was built with the Oculus XR Plugin loader enabled, but is attempting to run on a non-Oculus device.\nTo build for general Android devices, please disable the Oculus XR Plugin before building the Android player.\n\n\n");
Application.Quit();
}
if (supported != DeviceSupportedResult.Supported)
return;
try
{
if (!NativeMethods.LoadOVRPlugin(""))
Debug.LogError("Failed to load libOVRPlugin.so");
}
catch
{
// handle Android standalone build with Oculus XR Plugin installed but disabled in loader list.
}
}
#endif
SOLUTION
Made my build class extend IPreprocessBuildWithReport
public void OnPreprocessBuild(BuildReport report)
{
DisableXRLoaders(report);
}
///https://docs.unity3d.com/Packages/com.unity.xr.management#3.2/manual/EndUser.html
/// Do this as a setup step before you start a build, because the first thing that XR Plug-in Manager does at build time
/// is to serialize the loader list to the build target.
void DisableXRLoaders(BuildReport report)
{
XRGeneralSettingsPerBuildTarget buildTargetSettings;
EditorBuildSettings.TryGetConfigObject(XRGeneralSettings.k_SettingsKey, out buildTargetSettings);
if (buildTargetSettings == null)
{
return;
}
XRGeneralSettings settings = buildTargetSettings.SettingsForBuildTarget(report.summary.platformGroup);
if (settings == null)
{
return;
}
XRManagerSettings loaderManager = settings.AssignedSettings;
if (loaderManager == null)
{
return;
}
var loaders = loaderManager.activeLoaders;
// If there are no loaders present in the current manager instance, then the settings will not be included in the current build.
if (loaders.Count == 0)
{
return;
}
var loadersForRemoval = new List<XRLoader>();
loadersForRemoval.AddRange(loaders);
foreach (var loader in loadersForRemoval)
{
loaderManager.TryRemoveLoader(loader);
}
}
public void Awake() {
StartCoroutine(SwitchToVR(()=>{
Debug.Log("Switched to VR Mode");
}));
//For disable VR Mode
XRSettings.enabled = false;
}
IEnumerator SwitchToVR(Action callback) {
// Device names are lowercase, as returned by `XRSettings.supportedDevices`.
// Google original, makes you specify
// string desiredDevice = "daydream"; // Or "cardboard".
// XRSettings.LoadDeviceByName(desiredDevice);
// this is slightly better;
string[] Devices = new string[] { "daydream", "cardboard" };
XRSettings.LoadDeviceByName(Devices);
// Must wait one frame after calling `XRSettings.LoadDeviceByName()`.
yield return null;
// Now it's ok to enable VR mode.
XRSettings.enabled = true;
callback.Invoke();
}
My question is exactly the same as this one but for Android and not iOS.
Get URL from remote URL in webview and open it in safari
Anyone have an idea. I am creating a cross-platform app and I have used the Clayton's answer to get it to work for iOS with some tweaks to open with a controller. But when trying different methods on Android and it is not working. This is as close as I have gotten (which is what Aaron provided on that same page) and it is not quite right as it opens the remote web page in a new browser window as well in the apps webview:
$.floorView.addEventListener('load', function(e) {
if (e.url.indexOf("http") !== -1) {
// stop the event
e.bubble = false;
// stop the url from loading
$.floorView.stopLoading();
// open
Ti.Platform.openURL(e.url);
}
});
Thanks!
I'd listen to the beforeload event, although I'm not 100% sure if you can actually prevent the Webview from still continuing the load as well.
Another way would be to intercept these links via JS you load or inject (evalJS()) in the webpage. Then fire a Ti.App event and respond to it in Titanium.
The Titanium.UI.Webview has a specific property for intercepting links: onlink.
This is not implemented as an event because it is a callback and needs to return a boolean to tell the Webview whether or not to load the URL of the link.
Oddly, setting the onlink callback right away makes the URL immediately load in Safari, so I did it this way:
$.webview.addEventListener('load', function(e) {
$.webview.onlink = function(e) {
Ti.Platform.openURL(e.url);
return false;
};
});
You can of course check the e.url string and decide whether to open it internally or externally.
I think I may have figured it out. Thanks to those whose ideas and suggestions lead to this code.
It appears to be working as I want on iOS and Android. Any suggestions or issues that you guys have I would appreciate the feedback. Thanks!
if ("iOS") {
$.webView.addEventListener('beforeload', function(e) {
if (e.navigationType == Titanium.UI.iOS.WEBVIEW_NAVIGATIONTYPE_LINK_CLICKED) {
// stop the event
e.bubble = false;
// stop the url from loading
$.webView.stopLoading();
//opens up the clicked URL for bill in new webView
var link = e.url;
var args = {url: link,};
// open link in my default webView for iOS
var newWebView=Alloy.createController('defaultWebView', args).getView();
newWebView.open();
}
});
}
else if ("Android") {
$.webView.addEventListener('beforeload', function(e) {
if (e.url.indexOf("http") !== -1) {
function Parser(text) {
var html = text;
var urlRegex = /((http|https):\/\/(\w+:{0,1}\w*#)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%#!\-\/]))?)/gi;
this.getHTML = function() {
return html;
};
} // end Parser
var parser = new Parser(e.url);
html = parser.getHTML();
if (html != "url of $.webView") {
// stop it from loding in current webView
$.webView.stopLoading();
// open link in browser
Ti.Platform.openURL(html);
}
}
});
}
else {
.....................
}
I am using the SDL-2.0.3 along with NDK-r10e, I'm attempting to make the return button switch the app to the background so I tried to use the function SDL_MinimizeWindow() but It does nothing ! is this a bug or do I miss something ?
here is my code :
if(event.key.keysym.sym == SDLK_AC_BACK)
{
SDL_MinimizeWindow(window);
SDL_Log("window minimized !\n");
}
everything just work fine and I get the log message when the button is pressed but the window is not minimized
That doesn't appear to be supported on Android (there's not really anything corresponding to minimizing a "window" on Android, unless you count finishing an Activity).
The SDL_MinimizeWindow function looks like this:
void
SDL_MinimizeWindow(SDL_Window * window)
{
CHECK_WINDOW_MAGIC(window, );
if (window->flags & SDL_WINDOW_MINIMIZED) {
return;
}
SDL_UpdateFullscreenMode(window, SDL_FALSE);
if (_this->MinimizeWindow) {
_this->MinimizeWindow(_this, window);
}
}
Where _this is an SDL_VideoDevice *, which is set to point to an SDL_VideoDevice for the appropriate platform at runtime. The Android video driver only sets up the following 3 Window-related functions:
device->CreateWindow = Android_CreateWindow;
device->SetWindowTitle = Android_SetWindowTitle;
device->DestroyWindow = Android_DestroyWindow;
Trying to perform any other operations on an SDL_Window on Android is likely to do nothing.
Some further information in the form of a couple of lines of code from SDL_androidwindow.c:
window->flags &= ~SDL_WINDOW_RESIZABLE; /* window is NEVER resizeable */
window->flags |= SDL_WINDOW_FULLSCREEN; /* window is always fullscreen */
Does anyone know how I can remove the address bar from the Android browser to better view my web app and make it look more like a native app?
You can do that with the next code
if(navigator.userAgent.match(/Android/i)){
window.scrollTo(0,1);
}
I hope it helps you!
Here's the NON-jQuery solution that instantly removes the address bar without scrolling. Also, it works when you rotate the browser's orientation.
function hideAddressBar(){
if(document.documentElement.scrollHeight<window.outerHeight/window.devicePixelRatio)
document.documentElement.style.height=(window.outerHeight/window.devicePixelRatio)+'px';
setTimeout(window.scrollTo(1,1),0);
}
window.addEventListener("load",function(){hideAddressBar();});
window.addEventListener("orientationchange",function(){hideAddressBar();});
It should work with the iPhone also, but I couldn't test this.
If you've loaded jQuery, you can see if the height of the content is greater than the viewport height. If not, then you can make it that height (or a little less). I ran the following code in WVGA800 mode in the Android emulator, and then ran it on my Samsung Galaxy Tab, and in both cases it hid the addressbar.
$(document).ready(function() {
if (navigator.userAgent.match(/Android/i)) {
window.scrollTo(0,0); // reset in case prev not scrolled
var nPageH = $(document).height();
var nViewH = window.outerHeight;
if (nViewH > nPageH) {
nViewH -= 250;
$('BODY').css('height',nViewH + 'px');
}
window.scrollTo(0,1);
}
});
Referring to Volomike's answer, I would suggest replacing the line
nViewH -= 250;
with
nViewH = nViewH / window.devicePixelRatio;
It works exactly as I check on a HTC Magic (PixelRatio = 1) and a Samsung Galaxy Tab 7" (PixelRatio = 1.5).
The one below works for me every time..
This site also has a few other suggestions, but this no-nonsense, no-worry one is available in a github:gist and answers your question (pasted here for convenience):
function hideAddressBar()
{
if(!window.location.hash)
{
if(document.height < window.outerHeight)
{
document.body.style.height = (window.outerHeight + 50) + 'px';
}
setTimeout( function(){ window.scrollTo(0, 1); }, 50 );
}
}
window.addEventListener("load", function(){ if(!window.pageYOffset){ hideAddressBar(); } } );
window.addEventListener("orientationchange", hideAddressBar );
As far as I can tell, the combination of extra height added to the page (which caused problems for you) and the scrollTo() statement make the address bar disappear.
From the same site the 'simplest' solution to hiding the address bar is using the scrollTo() method:
window.addEventListener("load", function() { window.scrollTo(0, 1); });
This will hide the address bar until the user scrolls.
This site places the same method inside a timeout function (the justification is not explained, but it claims the code doesn't work well without it):
// When ready...
window.addEventListener("load",function() {
// Set a timeout...
setTimeout(function(){
// Hide the address bar!
window.scrollTo(0, 1);
}, 0);
});
The problem with most of these is that the user can still scroll up and see the addressbar.
To make a permanent solution, you need to add this as well.
//WHENEVER the user scrolls
$(window).scroll(function(){
//if you reach the top
if ($(window).scrollTop() == 0)
//scroll back down
{window.scrollTo(1,1)}
})
this works on android (at least on stock gingerbread browser):
<body onload="document.body.style.height=(2*window.innerHeight-window.outerHeight)+'px';"></body>
further if you want to disable scrolling you can use
setInterval(function(){window.scrollTo(1,0)},50);
Here's an example that makes sure that the body has minimum height of the device screen height and also hides the scroll bar. It uses DOMSubtreeModified event, but makes the check only every 400ms, to avoid performance loss.
var page_size_check = null, q_body;
(q_body = $('#body')).bind('DOMSubtreeModified', function() {
if (page_size_check === null) {
return;
}
page_size_check = setTimeout(function() {
q_body.css('height', '');
if (q_body.height() < window.innerHeight) {
q_body.css('height', window.innerHeight + 'px');
}
if (!(window.pageYOffset > 1)) {
window.scrollTo(0, 1);
}
page_size_check = null;
}, 400);
});
Tested on Android and iPhone.
I hope it also useful
window.addEventListener("load", function()
{
if(!window.pageYOffset)
{
hideAddressBar();
}
window.addEventListener("orientationchange", hideAddressBar);
});
Finally I Try with this. Its worked for me..
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_ebook);
//webview use to call own site
webview =(WebView)findViewById(R.id.webView1);
webview.setWebViewClient(new WebViewClient());
webview .getSettings().setJavaScriptEnabled(true);
webview .getSettings().setDomStorageEnabled(true);
webview.loadUrl("http://www.google.com");
}
and your entire main.xml(res/layout) look should like this:
<WebView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/webView1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
don't go to add layouts.
I found that if you add the command to unload, he keeps down the page, ie the page that move!
Hope it works with you too!
window.addEventListener("load", function() { window.scrollTo(0, 1); });
window.addEventListener("unload", function() { window.scrollTo(0, 1); });
Using a 7-inch tablet with android, www.kupsoft.com visit my website and check how it behaves page, I use this command in my portal.
I'm building a mobile AIR app (Android & IOS) with Adobe Flash Builder 4.6 and I'm having this annoying problem.
Because I want to 'catch' the back-key on Android devices I added the following code to my main class:
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDown);
private function keyDown(k:KeyboardEvent):void {
if(k.keyCode == Keyboard.BACK) {
backClicked(); // function handling the back-action, not important
k.preventDefault();
}
Now somewhere else - nested in some classes - I've got a textfield:
TF = new TextField();
TF.type = TextFieldType.INPUT;
But when I set focus on the textfield the soft keyboard does appear, but I can't type a single character. When I disable the keylistener: no problem.
Seems like the listener is overriding my input field. Is there any workaround on this?
I have also implemented the back button functionality for my mobile apps , but i used to register keydown event only when my particular view is activated and removed the registered when view get deactivated.
in <s:view ....... viewActivate ="enableHardwareKeyListeners(event)" viewDeactivate="destroyHardwareKeyListeners(event)">
// add listener only for android device
if (Check for android device) {
NativeApplication.nativeApplication.addEventListener(KeyboardEvent.KEY_DOWN, handleHardwareKeysDown, false, 0);
NativeApplication.nativeApplication.addEventListener(KeyboardEvent.KEY_UP, handleHardwareKeysUp, false, 0);
this.setFocus();
}
private function destroyHardwareKeyListeners(event:ViewNavigatorEvent):void
{
if (NativeApplication.nativeApplication.hasEventListener(KeyboardEvent.KEY_DOWN))
NativeApplication.nativeApplication.removeEventListener(KeyboardEvent.KEY_DOWN, handleHardwareKeysDown);
if (NativeApplication.nativeApplication.hasEventListener(KeyboardEvent.KEY_UP))
NativeApplication.nativeApplication.removeEventListener(KeyboardEvent.KEY_UP, handleHardwareKeysUp);
}
private function handleHardwareKeysDown(e:KeyboardEvent):void
{
if (e.keyCode == Keyboard.BACK) {
e.preventDefault();
// your code
} else {
}
}
private function handleHardwareKeysUp(e:KeyboardEvent):void
{
if (e.keyCode == Keyboard.BACK)
e.preventDefault();
}
May this can help you.